Copyright: Delphi  v.3.0 Copyright (c) 1982-1997 Borland International, Inc.


Delphi ヘルプへようこそ
Delphi ヘルプへようこそ1038001

検索したトピックが見つかりませんでした。ヘルプファイルに問題があるか，そのトピックへのリンクに問題があると考えられます。［目次］，［キーワード］または［テキスト検索］タブを使うとこのトピックを見つけられるかもしれません。また，ボーランドの Web サイト www.borland.com で最新のヘルプファイルが提供されていないか確認してください。

トピックを検索するには

1	オブジェクトインスペクタのプロパティ名またはイベント名の欄で［F1］を押します。

2	コードエディタ内で，プロパティ名，メソッド名，関数名，手続き名，イベント名，または型名の位置で［F1］を押します。

3	カテゴリ別にトピックをブラウズするために［目次］タブをクリックします。

4	［キーワード］タブをクリックすると索引項目のリストが表示されます。

5	［テキスト検索］タブをクリックするとその単語または語句が検索されます (Windows NT 3.51のみ)。


Action Editor ダイアログボックス
Action Editor ダイアログボックス1051001

参照

［Action Editor］ダイアログボックスには，選択したディスパッチャが管理する動作項目が表示されます。この動作項目によって Web サーバーアプリケーションは HTTP 要求メッセージへの応答を作成し，送信することができます。動作項目をディスパッチャに追加するには，このダイアログボックスを使います。

［Action Editor］ダイアログボックスを表示するには，Web ディスパッチャコンポーネントをフォームに配置し，右クリックしてから［アクションの設定］を選択します。

ダイアログボックスのオプション

［Action Item］リスト

［Action Item］リストにはディスパッチャに関連付けられた動作項目ごとに以下のパラメータが表示されます。

［Name］	TWebActionItem.Name。ほかのオブジェクトが参照するときに動作項目を特定する文字列

［PathInfo］	TWebActionItem.PathInfo。ほかのオブジェクトが参照するときに動作項目を特定する文字列

［Enabled］	TWebActionItem.Enabled。動作項目が，その MethodType および Path に一致する HTTP 要求メッセージに応答できるかどうか示す論理値

［Default］	TWebActionItem.Default。動作項目が，その MethodType および Path に一致する HTTP 要求メッセージに応答できるかどうか示す論理値

選択した動作項目のパラメータはオブジェクトインスペクタに表示されるので，そこで編集できます。

［追加(A)］ボタン

新しい動作項目をディスパッチャに追加します。オブジェクトインスペクタで動作項目を選択し，そのパラメータを編集できます。

［削除(D)］ボタン

選択した動作項目をディスパッチャから削除します。

［上へ(U)］ボタンと［下へ(N)］ボタン

動作項目の順序を変更します。動作項目は順に処理されるので，リスト内での順序は重要です。


Response Editor ダイアログボックス
Response Editor ダイアログボックス1051002

参照

このダイアログボックスでは，問い合わせテーブルプロデューサコンポーネント TQueryTableProducer の HTTP 応答メッセージの形式と内容を定義できます。このコンポーネントは，HTTP 応答メッセージの MIME 型コンテンツ作成用の Delphi の定義済みオブジェクトです。

［Response Editor］ダイアログボックスを表示するには，問い合わせ（Query）と問い合わせテーブルプロデューサ（QueryTableProducer）をフォームに配置します。問い合わせテーブルプロデューサを右クリックし，メニューから［レスポンスの設定］を選択します。

ダイアログボックスのオプション

［Field］リスト

このダイアログボックスの上部中央にある項目リストには，応答テーブルにある各項目の項目名と項目型が表示されます。オブジェクトインスペクタを使うと，強調表示した項目のプロパティを変更できます。

［テーブルプロパティ］

応答テーブルには以下のプロパティがあります。

［位置合わせ］

THTMLTableAttributes.Align。HTML ドキュメント内のテーブルの水平方向の位置合わせです。

［枠］

THTMLTableAttributes.Border。テーブル枠の幅。-1 の場合，枠なしになります。

［背景色］

THTMLTableAttributes.BgColor。HTML テーブルの背景色です。

［セル余白］

THTMLTableAttributes.CellPadding。HTML テーブルの各セル内の余白の量。値が -1 の場合，HTML テーブルのセルをパディングする方法を Web ブラウザが決定します。

［セル間隔］

THTMLTableAttributes.CellSpacing。HTML テーブルのセルの間隔。値が -1 の場合，HTML テーブルのセルの分離方法を Web ブラウザが決定します。

［表幅］

THTMLTableAttributes.Width。HTML テーブル全体の幅を，Web ブラウザウィンドウ幅のパーセンテージで表します。デフォルト値 100 の場合，テーブルがブラウザウィンドウ幅いっぱいに広がります。

［追加(A)］ボタン

応答テーブルに列を追加します。オブジェクトインスペクタを使ってタイトルを入力し，項目を選択します。

［削除(D)］ボタン

選択した列をテーブルから削除します。

［上へ(U)］ボタンと［下へ(N)］ボタン

選択した列を上 (テーブルの左端方向) または下 (テーブルの右端方向) に移動して，テーブル内の列の順序を変更します。

［すべての項目の追加］ボタン

問い合わせテーブルプロデューサに結び付けられたデータセット (問い合わせ) 内のすべての項目について列を作成します。

［デフォルトに戻す(O)］

選択した列のプロパティ設定をデフォルトに戻します。


フォームについて
フォームについて1001001

参照

フォームは Delphi のすべてのアプリケーションの基礎となるものです。フォームはコンポーネントです。フォームの上にほかのコンポーネントを配置してアプリケーションのインターフェースを構築します。

アプリケーションを開発するときには，メインフォームをカスタマイズし，その他のインターフェースとしてさらにフォームの追加やカスタマイズを行います。コンポーネントを追加してプロパティを設定することでフォームをカスタマイズします。

フォームはウィンドウであり，デフォルトで次のような標準ウィンドウの機能を備えています。

コントロールメニュー

アイコン化ボタンと最大化ボタン

タイトルバー

サイズ変更が可能なウィンドウ枠

これらの機能は，フォームのその他のプロパティと同様に設計時にオブジェクトインスペクタを使って変更できます。


参照1001002

フォームへのコンポーネントの追加

カスタムダイアログボックスの開発

コンポーネントユーザーインターフェースの作成

コンポーネントプロパティの設定

TForm コンポーネント

フォームコンポーネントの使い方


クライアント領域1001003

アクティブウィンドウのフォームの一部分を表示したり変更するための領域です。フォーム上でオブジェクトの位置を揃えるには，ドット表示のグリッドを使います。


スピードバーについて
スピードバーについて1001004

参照

Delphi のスピードバーはメニューコマンドのショートカットです。次の図はデフォルトのスピードバーです。スピードバーはスピードバーのスピードメニューで［プロパティ(R)］を選択すればカスタマイズできます。

デフォルトのスピードバーボタンについての詳細は上の図の各ボタンをクリックしてください。

スピードバーとコンポーネントパレットの間にある分割線を使うとスピードバーの横方向のサイズを変更できます。

スピードバーにはヘルプヒントがあります。ヘルプヒントを有効にするにはスピードバーのスピードメニューで［ヒントを表示(S)］を選択します。


参照1001005

コンポーネントパレット

スピードバーの構成

キーボードショートカット


プロジェクトを開くボタン1001006

［プロジェクトを開く］ダイアログボックスを表示します。このダイアログボックスでは，新しいプロジェクトを開くことができます。

このボタンはメニューコマンドの［ファイル(F)｜開く(O)］に相当します。


ファイルを開くボタン1001007

［ファイルを開く］ダイアログボックスを表示します。このダイアログボックスでは，新しいテキストファイルを開くことができます。

このボタンはメニューコマンドの［ファイル(F)｜開く(O)］に相当します。


すべて保存ボタン1001008

開いているプロジェクトで変更されたすべてのファイルを各ファイルの現在の名前で保存します。

プロジェクトを以前に保存していない場合は，ファイル名を入力するための［名前を付けて保存］ダイアログボックスが表示されます。

このボタンはメニューコマンドの［ファイル(F)｜すべて保存(V)］に相当します。


ファイルの保存ボタン1001009

コードエディタのアクティブファイルに対する変更を保存します。

ファイルを以前に保存していない場合は，ファイル名を入力するための［名前を付けて保存］ダイアログボックスが表示されます。

このボタンはメニューコマンドの［ファイル(F)｜上書き保存(S)］に相当します。


プロジェクトに追加ボタン1001010

現在開いているプロジェクトにコードエディタのアクティブファイルを追加します。

このボタンは次のメニューコマンドに相当します。

［ファイル(F)｜プロジェクトに追加(D)］

プロジェクトマネージャスピードメニューの［ファイルの追加(A)］


プロジェクトから削除ボタン1001011

［プロジェクトから削除］ダイアログボックスを表示します。このダイアログボックスでは，開いているプロジェクトから削除したいファイルを選択できます。

このボタンは次のメニューコマンドに相当します。

［ファイル(F)｜プロジェクトから削除(J)］

プロジェクトマネージャスピードメニューの［ファイルの削除(R)］


ユニットリスト表示ボタン1001012

［ユニットの表示］ダイアログボックスを表示します。このダイアログボックスでは，現在のプロジェクトのユニットを表示できます。

ユニットを選択すると，そのユニットがコードエディタのアクティブページになります。

このボタンはメニューコマンドの［表示(V)｜ユニット(U)］に相当します。


フォームリスト表示ボタン1001013

［フォームの表示］ダイアログボックスを表示します。このダイアログボックスでは，現在のプロジェクトのフォームを表示できます。

フォームを選択すると，そのフォームがアクティブフォームになります。

このボタンはメニューコマンドの［表示(V)｜フォーム(F)］に相当します。


フォーム/ユニット切り替えボタン1001014

フォームが選択されるとコードエディタをアクティブウィンドウにし，コードエディタが選択されるとフォームをアクティブウィンドウにします。

このボタンはメニューコマンドの［表示(V)｜フォーム/ユニットの切り替え(G)］に相当します。


フォームの新規作成ボタン1001015

空白フォームと新しいユニットを作成してプロジェクトに追加します。

このボタンはメニューコマンドの［ファイル(F)｜新規作成(N)］に相当します。


実行ボタン1001016

アプリケーションをコンパイルして実行します。

このボタンはメニューコマンドの［実行(R)｜実行(R)］に相当します。


実行停止ボタン1001017

プログラムの実行を一時停止し，実行するコードの次の行に実行ポイントを設定します。


トレースボタン1001018

強調表示されている実行ポイントからプログラムを実行します。プログラマが作成したルーチンを一度に 1 文ずつ実行したいときに［トレース］ボタンを使います。ルーチンが呼び出し先から戻ると，ルーチン呼び出しに続く文にデバッガが実行ポイントを設定します。

Delphi でコードが生成されたルーチンに実行ポイントがある場合，［トレース］ボタンを選択すると，ルーチン呼び出しに続く文に実行ポイントが設定されます。

メモ:	シンボリックデバッグ情報が無効の場合，［トレース］ボタンは使えません。

このボタンはメニューコマンドの［実行(R)｜トレース実行(T)］に相当します。


ステップボタン1001019

サブルーチンへ分岐せずに，プログラムを一度に 1 文ずつ実行します。デバッグする必要のないルーチンをプログラムが実行しようとしている場合に，プログラムのステップ実行が役に立ちます。

実行ポイントがルーチン呼び出しにある場合，［ステップ］ボタンを選択すると，そのルーチンの内部のトレースは行われず通常実行され，ルーチン呼び出しに続く文に実行ポイントが設定されます。

メモ:	シンボリックデバッグ情報が無効の場合，［ステップ］ボタンは使えません。

このボタンはメニューコマンドの［実行(R)｜ステップ実行(S)］に相当します。


スピードメニュー
スピードメニュー1001020

参照

Delphi のスピードメニューは現在利用できるコマンドをすばやく使えるようにするための機能です。

Delphi プログラミング環境では，次の構成要素でスピードメニューを利用できます。

位置合わせパレット

ブレークポイントリスト

呼び出し履歴

コードエディタ

コンポーネントパレット

フォーム

メニューデザイナ

オブジェクトブラウザ

オブジェクトインスペクタ

プロジェクトマネージャ

スピードバー

監視式

スピードメニューを表示するには，次のどちらかを実行します。

ウィンドウで右クリックする

カーソルがウィンドウ内にあるときに〔Alt〕+〔F10〕を押す


コードエディタ
コードエディタについて1001021

参照

Delphi の高機能エディタであるコードエディタでは，アプリケーションを実行するコードを表示して，次のような各種の強力な機能を利用できます。

Brief 方式の編集

色付き構文強調表示

複数回およびグループ単位の取り消し

各種の編集コマンド

Code Insight ツール

コマンドの多くはコードエディタスピードメニューから利用できます。

コードエディタをカスタマイズするには，［環境オプション］ダイアログボックスを使います。

コードエディタのトークンについてのヘルプ情報を表示するには，そのトークンにカーソルを合わせて〔F1〕を押します。

新しいプロジェクトを開くと，メインフォームユニット用のページがコードエディタに追加されます。

コンパイルエラーが発生すると，次のようになります。

コードエディタのメッセージボックスにエラーが表示される

エラーの発生した行が強調表示される


コードエディタでの別のファイルの表示
コードエディタでの別のファイルの表示1001022

そのファイルに関連付けられているタブをクリックします。


参照1001023

コードエディタの動作

コードの基本

エラーメッセージ

オブジェクトインスペクタ

プロジェクトマネージャ

コードエディタの操作

コードエディタでの別のファイルの表示

イベントハンドラの操作


最大表示ボタン1001024

ウィンドウを画面全体の大きさに表示します。


コードエディタ1001025

アクティブページにあるソースコードの一部分を表示したり変更するために使います。


ページタブ1001026

コードエディタで，開いているファイルの間を移動するためのものです。

コードエディタでほかのファイルに移動するには

対応するタブをクリックする


タイトルバー1001027

コードエディタのアクティブファイルの名前を表示します。


行と列のインジケータ1001028

コードエディタのカーソル位置を行と列で示します。最初の数値が行番号で，2 番目の数値が列番号です。


変更インジケータ1001029

コードエディタのアクティブページのファイルが前回の保存の後で変更されたかどうかを示します (変更されていなければ空白になります)。


モードインジケータ1001030

コードエディタが挿入モードか上書きモードかを示します。

挿入モード (デフォルト)。入力した文字はカーソル位置に挿入される

上書きモード。入力した文字はすでに入力されている文字を上書きして置き換える

2 つのモード間の切り替えには〔Ins〕を使います。


メニューデザイナについて
メニューデザイナについて1001031

Delphi のメニューデザイナを使うと簡単にフォームにメニューを追加できます。メニュー項目をメニューデザイナウィンドウに追加するだけで設計できます。メニュー項目の追加，削除，並べ替えを行うこともでき，プログラムを実行して結果を確認する必要はありません。アプリケーションのメニューは実行時と同じように常にフォーム上に表示されています。

メニュー構造全体をゼロから構築することも，Delphi のメニューテンプレート (設計済みのメニュー) の 1 つを基にして作り始めることもできます。

メニューを動的に変更してユーザーに追加の情報やオプションを提供することもできます。

メニューデザイナについての詳細は次のトピックを参照してください。

メニューデザイナを開く

メニューデザイナを使わないメニュー項目の編集

メニューデザイナスピードメニュー

メニューテンプレートの使い方

リソースファイルからのメニューのインポート

実行時のメニューのアクセスと編集


メニュータイトル領域1001032

メニュータイトルが表示される領域です。強調表示されているブロックをクリックすると，新しい項目がメニューに追加されます。


メニューコマンド領域1001033

メニューコマンドが表示される領域です。強調表示されているブロックをクリックすると，新しいメニューコマンドが追加されます。


オブジェクトインスペクタ
オブジェクトインスペクタについて1001034

参照

Delphi のオブジェクトインスペクタはアプリケーションの表示状態と，アプリケーション実行用のコードとの調整を行うための機能です。

オブジェクトインスペクタを使うと以下のことが行なえます。

フォームに配置したコンポーネント (またはフォームそのもの) に対して設計時プロパティを設定する

イベントハンドラを作成し，イベントハンドラ間で移動する

オブジェクトインスペクタ上部のオブジェクトセレクタには，アクティブなフォームにあるすべてのコンポーネントを含むドロップダウンリストが表示され，各オブジェクト型も示されます。ここで，現在のフォームにあるコンポーネントやフォームそのものをすばやく選択できます。

分割線をドラッグすると，オブジェクトインスペクタの列のサイズを変更できます。

オブジェクトインスペクタには次の 2 種類のページがあります。

  ［プロパティ］ページ

  ［イベント］ページ


参照1001035

コンポーネントプロパティの設定

コードの基本


オブジェクトインスペクタ プロパティページ
オブジェクトインスペクタ: プロパティページ1001036

参照

フォームにあるコンポーネントやフォームそのものに対して設計時プロパティを設定するには，オブジェクトインスペクタの［プロパティ］ページを使います。実行時プロパティは，イベントハンドラ内にソースコードを記述して設定できます。

［プロパティ］ページには，フォームで選択されているコンポーネントのプロパティだけが表示されます。

設計時にプロパティを設定すると，コンポーネントの初期状態が定義されます。


参照1001037

［イベント］ページ

プロパティエディタの使い方

コンポーネントプロパティの設定

ネストしたプロパティの表示


オブジェクトインスペクタ イベントページ
オブジェクトインスペクタ: イベントページ1001038

参照

フォームやコンポーネントをプログラムのイベントに関連付けるには，オブジェクトインスペクタの［イベント］ページを使います。［イベント］ページでイベントをダブルクリックすると，イベントハンドラが作成され，フォーカスがコードエディタに移ります。コードエディタでは，特定のイベントに対するコンポーネントやフォームの応答を指定するコードをイベントハンドラ内部に記述します。

［イベント］ページには，フォームで選択されているコンポーネントのイベントだけが表示されます。


参照1001039

共有イベントの表示とコーディング

デフォルト以外のイベントハンドラの検索

［プロパティ］ページ

プロパティエディタの使い方


オブジェクトセレクタ1001040

アクティブコンポーネントを表示します。このコンポーネントのプロパティとイベントを現在，編集しています。ドロップダウンリストを使ってコンポーネントを選択できます。


プロパティ列1001041

フォームで選択されているコンポーネントの設計時プロパティを一覧表示します。


値列1001042

プロパティの現在の値を表示します。各値は Delphi のプロパティエディタのいずれかを使って設定します。


オブジェクトインスペクタのタブ1001043

オブジェクトインスペクタの［プロパティ］ページと［イベント］ページを切り替えます。ページを切り替えるには，タブをクリックします。


アイコン化ボタン1001044

ウィンドウをアイコンにします。


スクロールバー1001045

カレントウィンドウにオブジェクトを表示しきれないときに，ウィンドウをスクロールしてオブジェクトの残りを表示するためのものです。ウィンドウをスクロールするには，上下のスクロール矢印をクリックするか，スクロールボックスをドラッグします。


コントロールメニュー1001046

コントロールメニューボックスをクリックすると，カレントウィンドウのコントロールメニューが開きます。


ハンドラ列1001047

イベントのイベントハンドラリンクを表示します。イベントに対してデフォルトイベントハンドラリンクを生成するには，ハンドラ列をダブルクリックします。


イベント列1001048

フォームで選択されているコンポーネントのイベントを一覧表示します。


プロジェクトマネージャについて
プロジェクトマネージャについて1001049

参照

Delphi のプロジェクトマネージャでは，プロジェクトに関連付けられているフォームファイルとユニットファイルが表示されます。表示されるファイルは .DPR ファイルの uses 節に指定されているものです。プロジェクトマネージャを使うと，アプリケーションプロジェクトの開発中にファイル間を簡単に行き来できます。

プロジェクトマネージャにはスピードメニューもあり，ウィンドウ領域のどこからでも右クリックすれば表示されます。

Delphi を起動したときには，［表示(V)｜プロジェクトマネージャ(P)］を選択してプロジェクトマネージャを表示します。デスクトップの設定を保存しておけば，プロジェクトを開いたときにデフォルトでプロジェクトマネージャウィンドウが開くようにできます。

複数のプロジェクト間でファイルを共有する場合は，プロジェクト内の各ファイルの場所がすばやくまた簡単にわかるのでプロジェクトマネージャを使うことをお勧めします。これは，プロジェクトで使うすべてのファイルを含むバックアップを作成するときに特に便利です。


プロジェクトマネージャを開く
プロジェクトマネージャを開く1001050

［表示(V)｜プロジェクトマネージャ(P)］を選択する

メモ:	プロジェクトマネージャを表示するには，プロジェクトを開いておかなくてはなりません。


プロジェクトマネージャを閉じる
プロジェクトマネージャを閉じる1001051

閉じるボタンをクリックする

コントロールメニューで［閉じる(C)］を選択する


参照1001052

プロジェクトマネージャスピードメニュー

プロジェクトのコンパイル，構築，実行

プロジェクトの操作

プロジェクトオプションの設定

バックアップ


追加ボタン1001053

［プロジェクトに追加］ダイアログボックスを表示します。このダイアログボックスでは，プロジェクトに追加するユニットファイル (.PAS) やフォームファイル (.DFM) を選択できます。

メモ:	このダイアログボックスで別のファイルを開くことができますが，そのファイルはプロジェクトに追加されません。


削除ボタン1001054

プロジェクトマネージャで選択されているファイルをプロジェクトから削除します。

メモ:	ファイルはプロジェクトディレクトリからは削除されません。


ユニット表示ボタン1001055

選択されているファイルのコードエディタウィンドウを表示します。ファイルが開いていない場合は自動的に開きます。


フォーム表示ボタン1001056

選択されているモジュールのフォームを表示します。選択されているユニットファイルにフォームが関連付けられていない場合，このボタンは使えません。


オプションボタン1001057

［プロジェクトオプション］ダイアログボックスを表示します。このダイアログボックスでは，コンパイラ指令，リンカオプション，出力ディレクトリ，条件定義，プロジェクトに追加するファイルを指定できます。


更新ボタン1001058

プロジェクトマネージャに表示されているファイルの内容をプロジェクトファイルの内容に一致させます。.DPR ファイルを手動で変更したとき以外は，このボタンは使えません。


ユニット列1001059

この列のファイル名をダブルクリックすると，選択されているユニットのソースが表示されます。選択されているユニットが開いていない場合は自動的に開きます。


フォーム列1001060

この列のファイル名をダブルクリックすると，選択されているフォームが表示されます。選択されているフォームが開いていない場合は自動的に開きます。

この列が空の場合は，ユニット列に表示されているユニットに関連付けられているフォームはありません。


ファイルステータスライン1001061

プロジェクトファイルの ファイル名と，プロジェクトファイル内のフォームとユニットの数を表示します。


パス列1001062

フォームファイルやユニットファイルのパス名を表示します。ユニットがまだ保存されていない場合はこの列は空になります。


メニューの設計
メニューの設計1001063

Delphi メニューデザイナを使うと，設計済みのメニューあるいはカスタマイズしたメニューを簡単にフォームに追加できます。フォームにメニューコンポーネントを追加し，メニューデザイナを開き，メニューデザイナウィンドウにメニュー項目を直接入力するだけでメニューを構築できます。設計時にメニュー項目を追加または削除したり，メニュー項目をドラッグアンドドロップして順序を入れ替えたりできます。

結果を確認するためにプログラムを実行する必要はありません。設計時のメニューは実行時とまったく同じようにフォームに表示されます。

コードを記述すれば，実行時にメニューを変更してユーザーにより多くの情報やオプションを提供することもできます。詳細については実行時のメニューのアクセスと編集を参照してください。


オブジェクトブラウザウィンドウ
オブジェクトブラウザウィンドウ1002001

参照

オブジェクトブラウザを使うと，アプリケーションのオブジェクト階層，ユニット，グローバルシンボル間を視覚的に移動できます。オブジェクトブラウザでは以下のようなことが行えます。

アプリケーション内のオブジェクト階層を視覚的に表示する

プログラムで使うユニットを一覧表示し，コンパイラ設定に基づいてインターフェース部または実現部で宣言されたシンボルを表示する

アプリケーション内のすべてのグローバルシンボルを一覧表示し，その宣言を表示し，ソースコード内の参照位置に移動する

オブジェクトブラウザにはスピードメニューがあり，参照中のシンボルを変更したり，表示オプションを選択したりできます。スピードメニューにアクセスするには，オブジェクトブラウザウィンドウ内で右クリックするか〔Alt〕+〔F10〕を押します。

オブジェクトブラウザにはインスペクタペインと詳細ペインの 2 つのサイズ変更可能なペインがあります。

オブジェクトブラウザウィンドウの各部についての詳細を参照するには，上のグラフィック内の領域をクリックしてください。

インスペクタペインまたは詳細ペインをサイズ変更するには

1.	カーソルを 2 つのペインの間に合わせ，カーソルが両向き矢印に変わるようにします。

2.	セパレータを左または右にドラッグします。

オブジェクトブラウザの使い方についての詳細は，次の各トピックを参照してください。

シンボルの参照

ブラウザでのシンボルの検索

フィルタの設定

オブジェクトブラウザの有効化


参照1002002

継承ツリー

オブジェクトブラウザのキーボードショートカット

［環境オプション］ダイアログボックスの［ブラウザ］ページ


インスペクタペイン1002003

参照中の領域のシンボルを表示します。ペイン内でシンボルを選択すると，そのシンボルの宣言，継承情報，参照をインスペクトできます。

オブジェクトブラウザを初めて開いたとき，オブジェクトの参照中なら，インスペクタペインにはオブジェクト継承ツリーが表示されます。このデフォルトは［環境オプション］ダイアログボックスの［ブラウザ］ページで変更できます。［環境オプション］ダイアログボックスは［ツール］メニューから［環境オプション(O)］を選択すると表示されます。

インスペクタの参照対象を変更するには

オブジェクトブラウザスピードメニューで［オブジェクト(O)］，［ユニット(U)］，［グローバルシンボル(G)］，または［シンボル(Y)］のいずれかを選択します。


詳細ペイン1002004

インスペクタペインで選択したオブジェクト，ユニット，グローバルシンボル，またはシンボルについての詳細を表示します。詳細ペインには 3 種類のページがあります。

［スコープ］ページ

インスペクタペインで選択したオブジェクト，ユニット，グローバルシンボル，またはシンボル内で宣言されたすべてのシンボルを一覧表示します。表示を変更したいときには，オブジェクトブラウザスピードメニューで［シンボル名でソート(S)］または［厳密な名前で表示(Q)］を選択します。

［継承］ページ

インスペクタペインで選択したオブジェクトの上位オブジェクトと下位オブジェクトからなる折りたたみ可能なローカルツリーを表示します。

［参照先］ページ

インスペクタペインで選択したシンボルがコード内に出現するすべてのファイル名と行番号を一覧表示します。シンボルに関する参照情報がない場合，そのシンボルはコード内で使われていないか，［シンボル情報(Y)］をオフにしてコンパイルしたユニットに含まれています。参照情報をダブルクリックすると，コード内のその行に移動します。


表示ボタン1002005

オブジェクトブラウザフィルタの表示を切り替えます。このフィルタを使うと参照するシンボルを制限できます。フィルタを追加または削除するには，このボタンをクリックします。

オブジェクトブラウザスピードメニューで［ヒントを表示(H)］を選択した場合，マウスをボタンの上に合わせるとそのボタンの名前が表示されます。


ステータスライン1002006

現在参照中のシンボル型を表示します。

オブジェクトブラウザスピードメニューで［ステータスライン(I)］を選択すると，ステータスラインの表示が切り替わります。


履歴リスト1002007

［履歴］ボタンをクリックすると［オブジェクトブラウザ履歴］ダイアログボックスが開き，前に参照したシンボルのリストが表示されます。一番最後に参照したシンボルが最初に表示されます。

以前の表示に戻るには，名前をダブルクリックします。


前に戻るボタン1002008

前に戻るボタンをクリックすると，前のオブジェクトブラウザ表示に戻ります。前に戻ると，参照中だった情報はすべて失われます。


オブジェクトブラウザの有効化
オブジェクトブラウザの有効化1002009

参照

オブジェクトブラウザは，コードからさまざまなシンボルを検索するためのものです。

オブジェクトブラウザを開くには

［表示(V)｜ブラウザ(R)］を選択します。

オブジェクトブラウザを開始する前に，プログラムをコンパイルする必要があります。プログラムのコンパイル方法についての詳細はプロジェクトのコンパイル，構築，実行を参照してください。

プロジェクトをコンパイルすれば，モジュールの interface 部で宣言されたシンボルは常にオブジェクトブラウザでインスペクトできます。［プロジェクトオプション］ダイアログボックスの [コンパイラ] ページで［デバッグ］オプションのチェックボックスを有効にすることによって情報を追加できます。次の表は［デバッグ］オプションのチェックボックスとオブジェクトブラウザに及ぼす影響の一覧です。

オプション	チェックマークを付けた場合

デバッグ情報(D)	モジュールの implementation 部で宣言されたシンボルを追加する

ローカルシンボル(L)	詳細ペインの［参照先］ページに行番号参照を追加する

シンボル情報(Y)	ルーチン内で宣言されるすべての識別子を追加する。つまり，シンボルは特定のルーチンのスコープ内でローカルである

メモ:	［ローカルシンボル(L)］と［シンボル情報(Y)］のオプションを有効にするには，［デバッグ情報(D)］にチェックマークを付けなくてはなりません。


参照1002010

オブジェクトブラウザウィンドウ

シンボルの参照

オブジェクトブラウザのキーボードショートカット

ブラウザでのシンボルの検索

フィルタの設定


シンボルの参照
シンボルの参照1002011

参照

オブジェクトブラウザを使ってシンボルを表示している場合，シンボルの宣言やオブジェクト階層，ソースコード内での implementation 部などを表示してさらにインスペクトできます。

インスペクタペインでシンボルをインスペクトするには

インスペクタペインでシンボルを選択します。選択したシンボルの内容を反映するように詳細ペインの内容が更新されます。

独自の宣言を持つオブジェクト，ユニット，グローバルシンボルまたはシンボルは［プロジェクトオプション］ダイアログボックスの［コンパイラ］ページの［デバッグ］オプションに基づいてさらに詳しくインスペクトできます。

インスペクタペインでシンボルを詳しくインスペクトするには

インスペクタペインでシンボルをダブルクリックします。

シンボルを選択すると，詳細ペインの前の内容がインスペクタペインに移り，選択したシンボルの宣言が詳細ペインに新しく一覧表示されます。表示されたシンボルをインスペクトできます。

コード内でインスペクト中のシンボルを表示するには，以下のどちらかを実行する

参照するシンボルを選択し，〔Ctrl〕+〔Enter〕を押す。コードエディタがアクティブウィンドウになり，カーソルが参照位置に置かれる

参照するシンボルを選択し，スペースキーを押すと強調表示中のソースコードがアクティブになる。スペースキーを押した後，アクティブペイン内で矢印を使ってシンボル間を移動でき，ソースコード内のシンボル参照を表示できる。アクティブなユニットで使われていないシンボルが見つかると，このコマンドは使用不可になる

スペースキーを押してもフォーカスはオブジェクトブラウザからコードエディタに移動しない

選択したシンボルが関数または手続きの場合，コードをインスペクトするとルーチンの implementation 部宣言が表示されます。選択したシンボルが定数，プロパティ，変数，型の場合，コードをインスペクトするとシンボルの宣言が表示されます。


参照1002012

オブジェクトブラウザの有効化

オブジェクトブラウザウィンドウ

オブジェクトブラウザのキーボードショートカット

ブラウザでのシンボルの検索

フィルタの設定


オブジェクトブラウザでのシンボルの検索
オブジェクトブラウザでのシンボルの検索1002013

参照

オブジェクトブラウザはインスペクタペインと詳細ペインの両方でインクリメンタルサーチを行います。つまり，あるルーチンを検索したい場合，ルーチン名を入力すると，入力した名前に最も近いシンボルにオブジェクトブラウザのフォーカスが移動します。

入力した文字はフィルタボタンと［履歴］ボタンの間に表示されます。現在の検索を取り消すには〔Esc〕を押します。

メモ:	オブジェクトブラウザはアクティブなペイン内のシンボルと一致しないインクリメンタルサーチ文字は受け付けません。

インクリメンタルサーチの文字をクリアするには，〔Esc〕を押します。

次を検索するには，〔Ctrl〕+〔N〕を押します。


参照1002014

シンボルの参照

オブジェクトブラウザの有効化

オブジェクトブラウザウィンドウ

オブジェクトブラウザのキーボードショートカット

フィルタの設定


継承ツリー
継承ツリー1002015

参照

オブジェクトブラウザでオブジェクトを参照中は，インスペクタペインに継承ツリーが表示されます。継承ツリーとは，アプリケーションで使うすべてのオブジェクトの上位/下位関係の詳細を示すアウトラインです。ツリーの枝によって相互につながるオブジェクトは，共通の基本オブジェクトを継承しています。

継承ツリーは詳細ペインの［継承］ページでも使われます。

継承ツリーの各オブジェクトノードにはアウトラインインジケータがあります。アウトラインインジケータはそのノードが展開可能かどうかを示します。

インジケータ	説明

ツリーのノードは折りたたまれ，継承オブジェクトは一覧表示されていない

ツリーのノードは展開され，継承オブジェクトが一覧表示されている

このオブジェクトを継承するオブジェクトは存在しない

継承ツリーのノードを展開または折りたたむには

ノードの左のアウトラインインジケータをクリックします。


参照1002016

オブジェクトブラウザウィンドウ


オブジェクトブラウザのキーボードショートカット
オブジェクトブラウザのキーボードショートカット1002017

オブジェクトブラウザ内の移動には次のキーを使います。

キー	動作

〔↑〕	1 シンボル上に移動する

〔↓〕	1 シンボル下に移動する

〔Ctrl〕+〔↑〕	選択したシンボルを変更せずに現在のペインを上にスクロールする

〔Ctrl〕+〔↓〕	選択したシンボルを変更せずに現在のペインを下にスクロールする

〔Ctrl〕+〔PgUp〕	スクロールせずに現在のペインの最上部に移動する

〔Ctrl〕+〔PgDown〕	スクロールせずに現在のペインの最下部に移動する

〔Home〕	現在のペインの最上部に移動する

〔End〕	現在のペインの最下部に移動する

〔Ctrl〕+〔Enter〕	選択したシンボルの実装部または宣言部にフォーカスを設定する

スペースキー	オブジェクトブラウザを閉じたりフォーカスを移動したりせずに，選択したシンボルのソースコードを強調表示する

〔Enter〕	現在選択しているシンボルを参照する

+	現在のノードを展開する

-	現在のノードを折りたたむ

*	ツリー全体を展開する

〔PgUp〕	現在のペインで 1 画面上に移動する

〔PgDn〕	現在のペインで 1 画面下に移動する

〔Esc〕	インクリメンタルサーチを取り消す

〔Ctrl〕+〔N〕	インクリメンタルサーチで次の一致を検索する

〔Tab〕	インスペクタペインと詳細ペインの間を移動する

次のキーボードコマンドは，オブジェクトブラウザでフィルタの設定と表示の変更を行うショートカットです。

キー	動作

〔Ctrl〕+〔C〕	定数フィルタを切り替える

〔Ctrl〕+〔F〕	関数と手続きフィルタを切り替える

〔Ctrl〕+〔T〕	型フィルタを切り替える

〔Ctrl〕+〔V〕	変数フィルタを切り替える

〔Ctrl〕+〔P〕	プロパティフィルタを切り替える

〔Ctrl〕+〔D〕	継承フィルタを切り替える

〔Ctrl〕+〔A〕	仮想フィルタを切り替える

〔Ctrl〕+〔1〕	Private フィルタを切り替える

〔Ctrl〕+〔2〕	Protected フィルタを切り替える

〔Ctrl〕+〔3〕	Public フィルタを切り替える

〔Ctrl〕+〔4〕	Published フィルタを切り替える

〔Ctrl〕+〔B〕	前に戻る

〔Ctrl〕+〔L〕	オブジェクトブラウザの履歴リストを開く

〔Ctrl〕+〔O〕	オブジェクト表示に切り替える

〔Ctrl〕+〔U〕	ユニット表示に切り替える

〔Ctrl〕+〔G〕	グローバルシンボル表示に切り替える

〔Ctrl〕+〔Y〕	シンボル表示に切り替える

〔Ctrl〕+〔S〕	詳細ペインの［スコープ］ページに切り替える

〔Ctrl〕+〔I〕	詳細ペインの［継承］ページに切り替える

〔Ctrl〕+〔R〕	詳細ペインの［参照先］ページに切り替える


フィルタの設定
フィルタの設定1002018

参照

オブジェクトブラウザを使って特定のシンボルを表示するようフィルタをかけることができます。たとえば，現在選択しているオブジェクトの変数だけを表示するよう選択できます。

設定可能なフィルタの一覧を次に示します。

定数

関数と手続き

型

変数

プロパティ

継承

仮想

Private

Protected

Public

Published

フィルタを設定するには，次のいずれかの操作をします。

フィルタの対応ボタンをクリックする

［環境オプション］ダイアログボックスの［ブラウザ]ページでシンボルフィルタを選択する。［環境オプション］ダイアログボックスはツールメニューから開く

フィルタのキーボードショートカットを押す

メモ:	インスペクタペインまたは詳細ペインでシンボルの横にあるグリフは，シンボルの型を識別します。場合によっては，シンボルの横に複数のグリフが表示されることもあります。2 番目の文字はシンボルをさらに詳しく説明し，シンボルの型を識別する文字の右に表示されます。


参照1002019

オブジェクトブラウザウィンドウ

シンボルの参照

オブジェクトブラウザのキーボードショートカット

ブラウザでのシンボルの検索


オブジェクトブラウザスピードメニュー
オブジェクトブラウザスピードメニュー1002020

参照	スピードメニュー

オブジェクトブラウザスピードメニューを使うと，各種のシンボルをすばやく参照したり，参照中のシンボルの表示を変更したりできます。

オブジェクトブラウザスピードメニューにアクセスするには

オブジェクトブラウザウィンドウ内のどこかで右クリックする

〔Alt〕+〔F10〕を押す

オブジェクトブラウザスピードメニューには次の項目があります。

オブジェクト(O)	アプリケーション内のすべてのオブジェクトに関する継承ツリーを表示します。

ユニット(U)	現在のプロジェクト内のユニットを表示します。

グローバルシンボル(G)	プロジェクト全体のグローバルシンボルを表示します。

シンボル(Y)	［シンボルを調べる］ダイアログボックスを開きます。

厳密な名前で表示(Q)	定義されているユニット名を付けてシンボルを表示します。

シンボル名でソート(S)	シンボルを名前のアルファベット順にソートします。

ヒントを表示(H)	フィルタボタンのヘルプヒントの表示を切り替えます。

ステータスライン(I)	ステータスラインの表示を切り替えます。


参照1002021

オブジェクトブラウザウィンドウ


オブジェクト(O) (オブジェクトズラウザスピードメニュー)
オブジェクト(O) (オブジェクトズラウザスピードメニュー)1002022

オブジェクトブラウザスピードメニューで［オブジェクト(O)］を選択すると，インスペクタペインにアプリケーション内のすべてのオブジェクトが表示されます。これらのオブジェクトは親子関係が示されるよう縦の継承ツリーとして配置されます。


ユニット(U) (オブジェクトズラウザスピードメニュー)
ユニット(U) (オブジェクトズラウザスピードメニュー)1002023

オブジェクトブラウザスピードメニューで［ユニット(U)］を選択すると，インスペクタペインにアプリケーションで使うすべてのユニットが一覧表示されます。


グローバルシンボル(G) (オブジェクトブラウザスピードメニュー)
グローバルシンボル(G) (オブジェクトブラウザスピードメニュー)1002024

オブジェクトブラウザスピードメニューで［グローバルシンボル(G)］を選択すると，インスペクタペインにアプリケーションで使うユニット内で宣言されたすべてのグローバル情報が表示されます。


シンボル(Y) (オブジェクトブラウザスピードメニュー)
シンボル(Y) (オブジェクトブラウザスピードメニュー)1002025

オブジェクトブラウザスピードメニューで［シンボル(Y)］を選択すると［シンボルを調べる］ダイアログボックスが開き，参照するシンボルを指定できます。

［シンボルを調べる］ダイアログボックス

このダイアログボックスは特定のシンボルを参照するために使います。

特定のシンボルを参照するには，次のどちらかを実行します。

編集ボックスにシンボル名を入力し，［OK］をクリックする

↓をクリックして前に入力したシンボルのリストからシンボルを選択し，［OK］をクリックする
矢印キーを使ってリストボックス内の移動もできる

［OK］をクリックすると，インスペクタペインにシンボルが表示され，詳細ペインにローカル情報が表示されます。

さらに，シンボルを定義したソースコードに移動したり，シンボル宣言をインスペクトしたりできます。コード内のシンボル参照についての詳細はシンボルの参照を参照してください。


厳密な名前で表示(G) (オブジェクトブラウザスピードメニュー)
厳密な名前で表示(Q) (オブジェクトブラウザスピードメニュー)1002026

オブジェクトブラウザスピードメニューで［厳密な名前で表示(Q)］を選択すると，シンボルの限定識別子が表示されます。このオプションがオフの場合は，シンボル名だけが表示されます。

このオプションは［環境オプション］ダイアログボックスの［ブラウザ］ページを使って設定できます。［環境オプション］ダイアログボックスはツールメニューから開きます。


シンボル名でソート(S) (オブジェクトブラウザスピードメニュー)
シンボル名でソート(S) (オブジェクトブラウザスピードメニュー)1002027

オブジェクトブラウザスピードメニューで［シンボル名でソート(S)］を選択すると，名前のアルファベット順にシンボルが表示されます。このオプションがオフの場合は，シンボルが宣言順にソートされます。

このオプションは［環境オプション］ダイアログボックスの［ブラウザ］ページを使って設定できます。


ステータスライン(I) (オブジェクトブラウザスピードメニュー)
ステータスライン(I) (オブジェクトブラウザスピードメニュー)1002028

オブジェクトブラウザスピードメニューで［ステータスライン(I)］を選択すると，ステータスライン の表示が切り替わります。


About the Component palette
About the Component palette 1003001

Section topics	参照

コンポーネントはすべての Delphi アプリケーションの基礎構築ブロックであり，Delphi ビジュアルコンポーネントライブラリの基本要素です。コンポーネントパレットの各ページタブはアプリケーションインターフェースの設計に使うコンポーネントを表すアイコングループを表示します。

コンポーネントパレットにはヘルプヒントが表示されます。カーソルをボタンの上に移動したまま 1 秒以上経過するとそのボタンの名前と簡単な説明がポップアップウィンドウ内にヘルプヒントとして表示されます。ヘルプヒントを使うには，コンポーネントパレットのスピードメニューで［ヒントを表示(S)］を選択します。

コンポーネントにはビジュアルコンポーネントと非ビジュアルコンポーネントがあります。コンポーネントごとにアプリケーションの制御に使う属性を指定します。属性にはプロパティ，イベント，メソッドがあります。

コンポーネントパレットとスピードバーの間にある分割線をドラッグすれば，コンポーネントパレットの水平方向のサイズを変更できます。

コンポーネントとその機能については次の各ぺージを参照してください。Click the component name to see its formal object definition in the Delphi Visual Class Library Reference.  Click links in each component�s description to see relevant topics in the Delphi User�s Guide or Delphi Developer�s Guide.

標準コンポーネント (Standard)

追加コンポーネント (Additional)

Win32 components

システムコンポーネント (System)

Internet components

データアクセスコンポーネント (Data Access)

データコントロールコンポーネント (Data Controls)

Decision Cube components

QReport components

Dialogs components

Windows 3.1 コンポーネント (Win 3.1)

Samples components

ActiveX components


See also1003002

Overview of components

Two views of components

Choosing the right component

Understanding components in forms

Setting component properties

Customizing the Component Palette

Component palette context menu

イベントの処理

コンポーネントの処理

ユーザーイベントについて

プロパティの設定

Common component tasks

例: Creating a Select File dialog box


Standard page components
Standard page components1003003

Section topics	参照

コンポーネントパレットの［Standard］ページのコンポーネントは Delphi アプリケーションで Windows の標準のコントロール要素を使えるようにします。

MainMenu	フォームのメニューを作成します。To access events for items in a main menu, add the MainMenu component to a form and double-click it to open the Menu Designer.

PopupMenu	フォームのポップアップメニューを作成します。To access events for items in a popup menu, add the PopupMenu component to a form and double-click it to open the Menu Designer.

Label	選択できない文字列 (タイトルなど) を表示します。See About Label.

Edit	1 行のみのデータを入力または変更できる編集領域を表示します。Edit is one of several Text controls.

Memo	複数行のデータを入力または変更できる編集領域を表示します。See About Memo.

Button	押しボタンコントロールを作成します。アクションを選択するときに使われます。See About Button.

CheckBox	Yes/No または True/False の切り替えができるオプションを表示します。チェックボックスを使うと互いに排他的でない複数の選択項目を同時に表示でき，その中から複数のチェックボックスを選択できます。See About CheckBox.

RadioButton	Yes/No または True/False の切り替えができるオプションを表示します。ラジオボタンを使うと互いに排他的な複数の選択項目を同時に表示でき，その中から 1 つのラジオボタンを選択できます。See About RadioButton.

ListBox	スクロールできる選択肢のリストを表示します。See About ListBox and Properties common to list controls.

ComboBox	リストボックスと編集ボックスに選択肢リストを表示します。編集ボックス領域にデータを入力することもリストボックス領域から項目を選択することもできます。See About ComboBox.

ScrollBar	リストまたはフォームの表示領域を変更できます。スクロールバーを使って指定した分ずつ移動することもできます。See About Scrollbar.

GroupBox	関連のあるオプションをフォーム上で 1 つにまとめるコンテナを作成します。See About GroupBox.

RadioGroup	フォーム上にラジオボタンのグループボックスを作成します。See About RadioGroup.

Panel	フォーム上に他のコンポーネントを入れるパネルを作成します。パネルを使うとツールバーやステータスラインを作成できます。See About Panel.


Additional page components
Additional page components1003004

Section topics	参照

コンポーネントパレットの［Additional］ページのコンポーネントは Delphi アプリケーションで特殊な Windows コントロール要素を使えるようにします。

BitBtn	ビットマップを表示できるボタンコンポーネントを作成します。See About BitBtn.

SpeedButton	キャプションではなくグリフを表示できるボタンを作成します。スピードボタンはパネル内で 1 つにまとめてツールバーを作成することがあります。See About SpeedButton.

MaskEdit	Edit コンポーネントと似ていますが，MaskEdit コンポーネントではデータ入力と表示の形式を指定できます。such as a postal code or phone number. MaskEdit shares the properties of other Text controls.

StringGrid	文字列データを行と列で表示するのに使うグリッドを作成します。StringGrid.is a superset of the features provided by the DrawGrid component.

DrawGrid	データを行と列で表示するのに使うグリッドを作成します。See About DrawGrid.

Image	ビットマップ，アイコン，メタファイルを表示します。See About Image.

Shape	楕円または円，長方形または正方形，角の丸い長方形または正方形などの幾何学図形を描画します。See About Shape.

Bevel	3 次元の輪郭のはっきりした線またはボックスを描画します。See About Bevel.

ScrollBox	Creates a resizeable container that automatically displays scrollbars when necessary.  See About ScrollBox.

CheckListBox	Displays a scrollable list similar to ListBox except that each item has a check box next to it. See List boxes and Properties common to list controls.

Splitter	Add a splitter to a form between two aligned controls to allow users to resize the controls at runtime by clicking and dragging the split line. See About Splitter.

StaticText	A non-editable text component like Label, except that it includes a window handle, which is useful when the component�s accelerator key must belong to a windowed control.  Use StaticText to provide users with feedback on the current state of the application.

Chart	The chart equivalent of TTable.  Place the component on a form and  right-click it to display the third-party developer�s Help topics.


Win32 page components
Win32 page components1003005

Section topics	参照

コンポーネントパレットの［Win32］ページのコンポーネントを使うと，Delphi アプリケーションで利用できる 32-bit Windows (Windows95/NT) user interface のコモンコントロールを使用できます。

TabControl	Analogous to a divider in a file cabinet or notebook, this component provides a set of mutually exclusive notebook style tabs.

PageControl	ぺージセットは，複数のページを持つダイアログボックスを作成するために使います。タブコントロールは，本の見出しに類似した使われ方をします。このコントロールを使って，同じウィンドウ内の情報を区分けする複数の論理ページまたはセクションを定義します。See About PageControl.

ImageList	イメージリストは同じサイズのイメージのコレクションで，各イメージはインデックスを使って参照します。イメージリストを使うとアイコンやビットマップの大規模な集合を効率よく管理できます。イメージリスト中のすべてのイメージは，ひとつの横長のスクリーンデバイス形式のビットマップに保持されます。イメージリストには，イメージを (アイコンの場合のように) 透過モードで描画するためのマスクに使うビットマップを入れることもできます。To create an image list, add the ImageList component to the form and double-click it to display the Image List Editor. Also see Properties common to list controls

RichEdit	リッチテキスト形式メモコントロールです。デフォルトではリッチテキストエディタは，フォントプロパティ (フォント名，サイズ，色，太字，斜体など)，形式プロパティ (位置揃え，タブ，インデント，番号付けなど)，および選択しているテキストの自動ドラッグアンドドロップをサポートしています。See About RichEdit and Text controls.

TrackBar	トラックバーコンポーネントは，調節の範囲を定義するバーとインジケータから構成されます。バーとインジケータはどちらもコントロールの現在値を表し，これらを使ってコントロールの値を変更できます。トラックバーはたくさんのオプションをサポートしています。トラックバーの方向を垂直または水平に設定できるほか，スライドインジケータとスライドバーの長さと高さおよびトラックバーの増分値の設定，またコントロールに目盛を表示するかどうかの指定が行えます。See About TrackBar.

ProgressBar	プログレスバーコンポーネントは，左から右に「塗りつぶされて」ていく長方形のバーで構成されます。このコンポーネントの例としては Windows エクスプローラでのファイルのコピーがあります。プログレスバーコントロールは，時間のかかる操作やバックグラウンドプロセスのフィードバックとして使います。このコントロールは，プロセスの進行状況をユーザーに目に見える形で伝えます。See About ProgressBar.

UpDown	値の増減を行う上下の矢印ボタンです。See About UpDown.

HotKey	任意のコンポーネントにホットキーを結び付けます。See About HotKey.

Animate	A Windows animation control window that silently displays an Audio Video Interleaved (AVI) clip, a series of bitmap frames like a movie.  See About Animate.

DateTimePicker	Displays a list box for entering dates or times.  Users can select a date from the calendar or select dates or times by scrolling with Up and Down arrows and by typing.  You must have the latest version of COMCTL32.DLL, usually located in the Windows\System or Windows\System32 directory.

TreeView	ツリービューコンポーネントを使うと，複数のオブジェクトのセットをその論理的な階層関係に基づいてインデントの付いたアウトラインとして制御し表示することができます。このコントロールには，アウトラインの展開と折りたたみを行うボタンも含まれています。ツリービューコンポーネントを使ってコンテナなどの階層を構成する要素のセットの関係を表示することができます。See About TreeView.

ListView	ListView コンポーネントを使うと，リストを表示することができます。リストビューはさまざまなビュー内のデータを表示します。See Properties common to list controls

HeaderControl	ヘッダーコントロールを使うと，テキストや数値の列の上に付けるヘッダー (見出し) を表示することができます。コントロールを複数に分割することで，複数の列のヘッダーを作成できます。ヘッダーのタイトルの要素は，左，右，中央に揃えることができます。ヘッダーの各部分は，ユーザーがクリックしたときに特定の機能を果たすコマンドボタンとして動作するように設定できます。See About HeaderControl.

StatusBar	画面最下部にある動作の状態を表示する領域です。See About StatusBar.

ToolBar	 Manages tool buttons and other controls, arranging them in rows and automatically adjusting their sizes and positions.  See About ToolBar and Working with toolbars and cool bars.

CoolBar	Displays a collection of windowed controls (CoolBand objects) within movable, resizable bands. The user positions the controls by dragging the sizing grip to the left of each band.  See About CoolBar and Working with toolbars and cool bars.


System page components
System page components1003006

Section topics	参照

コンポーネントパレットの［System］ページのコンポーネントは Delphi アプリケーションで特殊システムコントロール要素を使えるようにします。

Timer	イベントを指定した時間間隔で実行します。これは非ビジュアルコンポーネントです。You write the code that you want to occur at the specified time inside the timer component's OnTimer event. See About Timer

 	PaintBox	Specifies a rectangular area on a form that provides boundaries for application painting.  See About PaintBox

MediaPlayer	マルチメディアのビデオと音声のファイルの再生や録画と録音に使う VCR スタイルのコントロールパネルを表示します。See About MediaPlayer

OleContainer	フォームに OLE クライアント領域を作成します。See About OleContainer and Using OLE Automation

DdeClientConv	DDE サーバーアプリケーションにクライアントを接続します。これは非ビジュアルコンポーネントです。See DDE についてClientConv

DdeClientItem	DDE 対話時に転送する DDE クライアントデータを指定します。これは非ビジュアルコンポーネントです。See DDE についてClientItem

DdeServerConv	DDE クライアントアプリケーションにサーバーを接続します。これは非ビジュアルコンポーネントです。See DDE についてServerConv

DdeServerItem	DDE 対話時に転送する DDE サーバーデータを指定します。これは非ビジュアルコンポーネントです。See DDE についてServerItem


Internet page components
Internet page components1003007

Section topics	参照

The components on the Internet page (available only in Delphi Client/Server edition) of the Component palette offer a variety of internet access protocols for your Delphi applications:

ClientSocket	Add to a form or data module to turn an application into a TCP/IP client. ClientSocket specifies a desired connection to a TCP/IP server, manages the open connection, and terminates the completed connection. See Using client sockets and Working with sockets

ServerSocket	Add to a form or data module to turn an application into a TCP/IP server.  ServerSocket listens for requests for TCP/IP connections from other machines and establishes connections when requests are received.  See Using server sockets and Working with sockets

WebDispatcher	Converts an ordinary data module to a Web module and enables the Web server application to respond to HTTP request messages.  See About WebDispatcher and The Structure of a Web server application

PageProducer	Converts an HTML template into a string of HTML commands that can be interpreted by a client application such as a Web browser. The commands and HTML-transparent tags are replaced with customized content by the OnHTMLTag event.  See Using page producer components

QueryTableProducer	Assembles a sequence of HTML commands to generate a tabular display of the records from a TQuery object, which obtains its parameters from an HTTP request message.  See Using TQueryTableProducer

DataSetTableProducer	Assembles a sequence of HTML commands to generate a tabular display of the records from a TDataSet object.  This allows an application to create images of a dataset for an HTTP response message. See Using TDataSetTableProducer

FTP	Invisible ActiveX control provides easy access for Internet File Transfer Protocol (FTP) services for transferring files and data between a remote and local machine.

HTML	Invisible ActiveX control implements an HTML viewer, with or without automatic network retrieval of HTML documents, and provides parsing and layout of HTML data, as well as a scrollable view of the selected HTML page. The HTML component can also be used as a non-visual HTML parser to analyze or process HTML documents.

HTTP	Invisible ActiveX control implements the HTTP Protocol Client, allowing users to directly retrieve HTTP documents if no browsing or image processing is necessary.

NNTP	Invisible ActiveX Client Control allows applications to access Networking News Transfer Protocol (NNTP) news servers. It provides news reading and posting capabilities.

POP	Invisible ActiveX control that retrieves mail from UNIX or other servers supporting POP3 protocol.

SMTP	ActiveX control that gives applications access to SMTP mail servers and mail posting capabilities.

TCP	Invisible Winsock ActiveX Control implements the Transmission Control Protocol for both client and server applications, providing easy access to TCP network services.

UDP	Invisible WinSock ActiveX Control provides easy access to User Datagram Protocol (UDP) network services. It implements WinSock for both client and server and represents a communication point utilizing UDP network services. It can also be used to send and retrieve UDP data.


Data Access page components
Data Access page components1003008

Section topics	参照

コンポーネントパレットの［Data Access］ページのコンポーネントは Delphi アプリケーションでデータベースアクセス要素を使えるようにします。

DataSource	TTable，TQuery，TStoredProc コンポーネントとデータベース対応のコンポーネント (TDBGrid など) を結び付けるために使います。See Working with data sources

Table	BDE を介して物理データベーステーブルからデータを取り出し，TDataSource コンポーネントを使って 1 つまたは複数のデータベース対応のコンポーネントに送ります。または，コンポーネントから受け取ったデータを BDE を介して物理データベースに送ります。See Working with tables

Query	SQL 文を使って BDE を介して物理データベーステーブルからデータを取り出し，TDataSource を介して 1 つまたは複数のデータベース対応のコンポーネントにそのデータを送ります。BDE を介してコンポーネントから物理データベースにデータを送る場合も SQL 文を使います。See Working with queries

StoredProc	サーバーのストアドプロシージャにアプリケーションがアクセスできるようにします。コンポーネントから受け取ったデータを BDE を介して物理データベースに送ります。See Working with stored procedures

Database	データベース (特にユーザーのログインとパスワードが必要なリモートデータベース) に固定的な接続を設定します。See Connecting to data bases

Session	TSession コンポーネントは，TDatabase コンポーネントのグループに結び付けることで，そのグループを全体的に制御することができます。Delphi のデータベースアプリケーションではデフォルトの TSession コンポーネントが自動的に作成されます。明示的に TSession コンポーネントを使う必要があるのは，マルチスレッドのデータベースアプリケーションを開発する場合だけです。各データベーススレッドごとに 1 つずつセッションコンポーネントが必要です。See Managing database sessions

BatchMove	テーブル構造またはそのデータをコピーします。テーブル全体をデータベース間で移動するのに使えます。See Copying data and table structures

UpdateSQL	TUpdateSQL コンポーネントを使うと，読み出し専用データセットに対する更新を「キャッシュ」することができます。また，TUpdateSQL コンポーネントが提供する問い合わせとともに使えば，その基になるデータセットを更新することができ，実質的に読み出し専用のデータセットを変更することができるようになります。データセットの UpdateObject プロパティを設定することによって，TUpdateSQL コンポーネントをデータセットに結び付けます。キャッシュされている更新を適用するときに，データセットは自動的に TUpdateSQL コンポーネントを使います。See About UpdateSQL

Provider	Encapsulates the mechanism for providing data from a multi-tiered application server to a client dataset in a desktop client application.  See Working with a provider component and Creating a multi-tiered application

ClientDataSet	Implements a database-independent dataset component that can be used independently in a single-tiered application, or as a client dataset in the client application portion of a multi-tiered database application.  See Creating and using a client dataset

RemoteServer	Provides a remote server connection in a client application that is part of a multi-tiered application.  See Establishing and maintaining a connection to an application server


Data Controls page components
Data Controls page components1003009

Section topics	参照

コンポーネントパレットの［Data Controls］ページのコンポーネントは Delphi アプリケーションでデータベースコントロール要素を使えるようにします。

DBGrid	データベース対応のカスタムグリッドです。表計算ワークシートに似た表形式でデータを表示または編集できます。列の可視性，表示形式，順序などを指定するには TField プロパティを活用してください。このプロパティはフィールドエディタで設定できます。See Working with grids

DBNavigator	データベース対応のレコード操作ボタンです。テーブルの現在のレコードポインタを前後に移動できます。テーブルを Insert 状態，Edit 状態，Browse 状態のいずれかにしたり，新しいレコードまたは変更したレコードを登録したり，更新したデータを取り出して表示を更新したりもできます。See Navigating and manipulating records

DBText	データベース対応のラベルです。カレントレコードのフィールド値を表示します。See Displaying data as labels

DBEdit	データベース対応の編集ボックスです。カレントレコードのフィールドを表示または編集します。See About DBEdit

DBMemo	データベース対応のメモボックスです。カレントレコードの BLOB テキストを表示または編集します。See About DBMemo

DBImage	データベース対応のイメージボックスです。カレントレコードのビットマップ BLOB  イメージの表示，切り取り，貼り付けをします。See About DBImage

DBListBox	データベース対応のリストボックスです。テーブルの列の値をスクロール可能なリスト形式で表示します。See About DBListBox

DBComboBox	データベース対応のコンボボックスです。テーブルの列の値をスクロール可能なリスト形式で表示したり，編集したりできます。See About DBComboBox

DBCheckBox	データベース対応のチェックボックスです。カレントレコードの論理データフィールドを表示または編集できます。See About DBCheckBox

DBRadioGroup	データベース対応のラジオボタングループです。列の値を表示または設定します。See About DBRadioGroup

DBLookupListBox	DBLookupListBox はデータベース対応のリストボックスで，データセットに対して定義された参照フィールドまたは二次データソース，データフィールド，およびキーのソースのどちらかから表示項目のリストを派生させます。いずれの場合でも，有効な値を設定するための限定された選択肢のリストがユーザーに提供されます。ユーザーがリスト項目を 1 つ選ぶと，基となるデータセット内の対応するフィールド値が変更されます。See About DBLookupListBox.
参照フィールドを使うリストボックス項目を指定するためには，コントロールをリンクするデータセットではすでに参照フィールドが定義されていなければなりません。See Defining a lookup field

DBLookupComboBox	DBLookupComboBox はデータベース対応のコンボボックスで，データセットに対して定義された参照フィールドまたは二次データソース，データフィールド，およびキーのソースのどちらかから表示項目のリストを派生させます。いずれの場合でも，有効な値を設定するための限定された選択肢のリストがユーザーに提供されます。ユーザーがリスト項目を 1 つ選ぶと，基となるデータセット内の対応するフィールド値が変更されます。See About DBLookupComboBox.
参照フィールドを使うリストボックス項目を指定するためには，コントロールをリンクするデータセットではすでに参照フィールドが定義されていなければなりません。See Defining a lookup field

DBRichEdit	A multiline edit control that can display and edit a rich text memo field in a dataset. See About DBRichEdit

DBCtrlGrid	DBCtrlGrid コントロールは，複数のレコードの複数のフィールドを表グリッド形式で表示します。グリッドの各セルには 1 つのレコードの複数のフィールドが表示されます。See About DBControlGrid.

DBChart	Place the component on a form and right-click it to display the third-party developer�s Help topics.


Decision Cube page components
Decision Cube page components1003010

Section topics	参照	About Decision Cube

The components on the Decision Cube page of the Component palette (available only in Delphi Client/Server edition) add multidimensional data analysis features to your Delphi applications. The Decision Cube components provide cross tabulation of tables and graphs, drill down, pivot, and aggregation to help users visual data for decision-making purposes:

DecisionCube	A multidimensional data store. See Using decision cubes

DecisionQuery	Specialized form of TQuery used to define the data in a decision cube. See Using decision queries

DecisionSource	Defines the current pivot state of a decision grid or a decision graph.  See Using decision sources

DecisionPivot	Use to open or close decision cube dimensions or fields by pressing buttons.  See Using decision pivots

DecisionGrid	Displays single and multidimensional data in table form.  See Creating decision grids and Using decision grids

DecisionGraph	Displays fields from a decision grid as a dynamic graph that changes when dimensions are modified. See Using decision graphs


See also1003011

Guidelines for using decision support components

Using decision support components


QReport page components
QReport page components1003012

Section topics	参照

The Quick Report components on the QReport page of the Component palette enables you to visually design Quick Reports.  You build reports with bands, adding titles, page headers and footers, multiple detail sets, summaries, group headers and footers.  You can report from any DataSource, including TTable, TQuery, lists, arrays, and so on.  Use the on-screen preview to check your results.  Automatically perform calculations like summary and counting of fields.  You can reset calculations at group level.

To see the third-party developer�s help, place the component on a form and right-click it.

QuickRep	The basic report form on which you build all your reports. It is a visual component which takes the shape of the currently selected paper size. You create reports by dropping bands and printable components on the TQuickRep component and connecting it to a dataset.

QRSubDetail	Links additional datasets into a report. Typically you would set up a master detail relationship between table or query components and create a similar relationship with TQRSubDetail components.

QRBand	Drop bands on a TQuickRep component and set the BandType property to tell how the band will behave during report generation.

QRChildBand	If you have bands with expanding components and want other components to be moved down accordingly you can create a child band and put the moving components on it. It�s also useful if you have very long bands that span multiple pages.

QRGroup

QRLabel	Prints static or other non-database text. Enter the text to be displayed in the Caption property. You can split text on multiple lines and even multiple pages.

QRDBText	A data-aware version of the TQRLabel that prints the value of a database field. Calculated fields and text field types can be printed, including String fields, various numeric fields, date fields and memo fields. Text can span multiple lines and pages. You connect the component to the data field by setting the DataSource and DataField properties. Unlike regular data-aware components, TQRDBText works even with dataset controls disabled to improve speed.

QRExpr	Prints database fields, calculations, and static text. Input a valid QuickReport expression in the Expression property.

QRSysData	Prints system information such as report title, current page number, and so on. Select the data to print in the Data property. Set any preceding text in the Text property.

QRMemo	Prints a large amount of text that does not come from a database field. It can be static text or you can change it during report generation. You can set the field to expand vertically as needed and then span multiple pages if necessary.

QRRichText

QRDBRichText

QRShape	Draws simple shapes like rectangles, circles, and lines on a report.

QRImage	Displays a picture on a report. Supports all image formats supported by the Delphi TPicture class.

QRDBImage	Prints images stored in binary (BLOB) fields. Prints all graphics formats supported by Delphi.

QRCompositeReport

QRPreview

QRChart


Dialogs page components
Dialogs page components1003013

Section topics	参照

コンポーネントパレットの［Dialogs］ページのコンポーネントは Delphi アプリケーションで Windows のコモンダイアログボックスを使えるようにします。コモンダイアログボックスにより一貫したファイル操作 (ファイルのオープン，保存，印刷など) ができます。

コモンダイアログボックスを開くにはその Execute メソッドを呼び出します。Execute は次の論理値のどちらかを返します。

ダイアログボックスを確定するため［OK］を選択すると，True を返す

［キャンセル］を選択するか変更結果を保存しないでダイアログボックスを終了すると，False を返す

コモンダイアログボックスコンポーネント (PrinterSetup コンポーネントを除きます) は必ずオブジェクトインスペクタの Options にプロパティセットを持っています。Options プロパティはコモンダイアログボックスの形式と動作を指定します。Options プロパティを表示するにはオブジェクトインスペクタで Options をダブルクリックします。

ダイアログボックスをプログラムで閉じるには CloseDialog メソッドを使う

実行時にダイアログボックスの位置を処理するには Handle，Left，Top，Position の各プロパティを使う

OpenDialog	アプリケーションで Windows のコモンダイアログボックス［ファイルを開く］を使えるようにします。開くファイルの名前をこのダイアログボックスで指定できます。See Selecting files to open

SaveDialog	アプリケーションで Windows のコモンダイアログボックス［ファイル名を付けて保存］を使えるようにします。保存するファイルの名前をこのダイアログボックスで指定できます。See Saving files

OpenPictureDialog	アプリケーションで Windows のコモンダイアログボックス［フォントの指定］を使えるようにします。フォント，サイズ，スタイルをこのダイアログボックスで指定できます。See Selecting files to open

SavePictureDialog	Displays a modal Windows dialog box for entering file names and saving graphics files. Identical to Save dialog box except that it has an image preview region. See Saving files

FontDialog	アプリケーションで Windows のコモンダイアログボックス［フォントの指定］を使えるようにします。フォント，サイズ，スタイルをこのダイアログボックスで指定できます。About FontDialog

ColorDialog	アプリケーションで Windows コモンダイアログボックス［色の設定］を使えるようにします。色をこのダイアログボックスで指定できます。

PrintDialog	アプリケーションで Windows のコモンダイアログボックス［印刷］を使えるようにします。印刷明細 (印刷するページ範囲や印刷部数など) をこのダイアログボックスで指定できます。About PrintDialog

PrinterSetupDialog	アプリケーションで Windows コモンダイアログボックス［プリンタの設定］を使えるようにします。このダイアログボックスでプリンタの変更と設定ができます。About PrinterSetupDialog

FindDialog	アプリケーションで Windows コモンダイアログボックス［検索］を使えるようにします。このダイアログボックスで検索文字列を指定できます。About Windows Common Dialogs

ReplaceDialog	アプリケーションで Windows コモンダイアログボックス［置換］を使えるようにします。このダイアログボックスで検索文字列と置換文字列を指定できます。About Windows Common Dialogs


Windows 3.1 Components
Windows 3.1 page components1003014

Section topics	参照

コンポーネントパレットの Windows 3.1 ページのコンポーネントを使うと，Delphi アプリケーションで利用できる Windows 3.1 のコントロール要素を利用できます。Many of these older controls implement the same behavior as more recent specialized 32-bit Windows controls.

Important:  When creating new applications, do not use these controls.
The following table indicates which control should be used instead:

Win 3.1 control	Replace with	Palette page of new control

DBLookupList	DBLookupListBox	Data Controls

DBLookupCombo	DBLookupComboBox	Data Controls

TabSet	TabControl	Win32

Outline	TreeView	Win32

Header	HeaderControl	Win32

NoteBook	PageControl	Win32

TabbedNoteBook	PageControl	Win32

DBLookupList	データベース対応のリストボックスです。実行時に別のテーブルの列で参照した値を表示します。

DBLookupCombo	データベース対応のコンボボックスです。実行時に別のテーブルの列で参照した値を表示します。

TabSet	ノートブック型タブを作成します。Notebook コンポーネントと一緒に使うとページを変更できます。

Outline	各種のアウトライン形式で情報を表示します。

TabbedNotebook	各ページが固有のコントロールセットを持つ複数のページが入るコンポーネントを作成します。ぺージを選択するにはページの最上部のタブをクリックします。

Notebook	複数ぺージが入るコンポーネントを作成します。TabSet コンポーネントと一緒に使うとページを変更できます。

Header	データを表示するための領域を作成します。表示するデータ量に合わせて各セクションのサイズを変更できます。

FileListBox	Displays a scrolling list of files in the current directory.

DirectoryListBox	Displays the directory structure of the current drive. Users can change directories in a directory list box.

DriveComboBox	Displays a scrolling list of available drives.

FilterComboBox	Specifies a filter or mask to display a restricted set of files.


Samples page components
Samples page components1003015

Section topics	参照

The components on the Sample page of the Component palette are examples of customized components that you can build and add to the Component Palette. Source code to these sample components is included in the DELPHI\SOURCE\SAMPLES directory of the default installation.

Gauge

ColorGrid

SpinButton

SpinEdit

DirectoryOutline

Calendar

IBEVentAlerter


ActiveX page components
ActiveX page components1003016

Section topics	参照

The components on the ActiveX page of the Component palette are ActiveX objects, complete, portable working applications created by third-party developers.  To use these components, you must first open an ActiveX form with a current ActiveX library project.  After placing a component on the ActiveX form, right-click it to display Properties and other commands or dialog boxes for configuring the component�s functionality or setting its values.  The Properties dialog box or other controls contain Help buttons that display the developer�s Help system for the component.

Chartfx	Lets you create highly customized charts.  Choose Properties to display a tabbed control panel that lets you define the values, appearance, and end-user functionality of the chart component.

VSSpell	Visual Speller, a customizable spelling checker.

F1Book	Formula One, a spreadsheet including a full featured Designer.

VtChart	Lets you create true 3D charts.

Graph	Pinnacle Graph, another implementation of a 2D graph designer.


Common component tasks
Common component tasks1003017

参照

アプリケーションインターフェースを設計する場合，コンポーネントごとに異なるのではなく同じ手順を使えると便利です。次にそのような手順の例を示します。詳細は次の各トピックを参照してください。

ヘルプヒントの提供

コンポーネントの位置合わせ

キーボードイベントの処理

マウスイベントの処理

ドラッグアンドドロップイベントの処理

フォーカスの設定

タブ順の設定

コンポーネントの有効化と無効化


See also1003018

コンポーネントパレットのカスタマイズ


Using the Form component
Using the Form component1003019

参照

アプリケーションには複数のフォームが含まれています。メインフォーム (一次ユーザーインターフェース)，ダイアログボックス，二次ウィンドウ (たとえば OLE 2.0 データを表示するウィンドウ) などがあります。フォームの設計には Delphi が用意している各種のフォームテンプレートを使えます。設計したフォームをテンプレートとして保存すれば他のプロジェクトでも使えます。

フォームに対する操作	フォームオブジェクトへのフィールドの追加	ダイアログボックスの作成	DLL としてのフォームの再利用	コンポーネントとしてのフォームの作成

使い方

実行時に他の開いているウィンドウ (プロジェクトマネージャまたは位置合わせパレットなど) の上にフォームを重ねるには FormStyle プロパティに fsStayOnTop を設定する

フォームのデフォルトのスクロールバーを削除するには HorzScrollBar と VertScrollBar の両プロパティの値を変更する

フォームを MDI フレームまたは MDI 子にするには FormStyle プロパティを使う

フォームの境界のスタイルを変更するには BorderIcons と BorderStyleの両プロパティの値を変更する (結果は実行時に表示される)

最小化フォームのアイコンを変更するには Icon プロパティを使う

アプリケーションウィンドウでフォームの最初の位置を指定するには Position プロパティを使う

フォームの最初の状態 (最小化，最大化，通常) を指定するには WindowState プロパティを使う

実行時にフォームの作業領域を定義するには ClientHeight と ClientWidth の両プロパティを使う (ClientHeight と ClientWidth はフォーム境界内の領域を表し，Height と Width はフォーム全体を表す)

実行時にフォームで最初にフォーカスを受け取るコントロールを指定するには ActiveControl プロパティを使う

選択しているコントロールに関係なくすべてのキーボードイベントをフォームに渡すには KeyPreview プロパティを使う

複数のメニューからメニューを指定するには Menu プロパティを使う


See also1003020

コンポーネントパレット

コンポーネントパレットのカスタマイズ

フォームの基本

TForm リファレンス


Responding to user events
About user events1003021

参照

イベント駆動型のプログラミングの場合，ユーザーイベントがアプリケーション論理の主要部分になります。ユーザーイベントはグラフィカルユーザーインターフェース (GUI) の要素に対応しています。たとえば，ほとんどのコンポーネントはユーザーがコンポーネントをクリックしたときに応答するように処理を作成できる OnClick イベントを持っています。そうでないイベント (フォームの OnActivate など) はユーザーが発生させるのではなくプログラムコードが発生させます。イベントに応答するように作成したコードをイベントハンドラといいます。

各ユーザーイベントの処理方法については次の各トピックを参照してください。

ボタンクリックイベント	キーボードイベント	マウスイベント	ドラッグアンドドロップイベント


See also1003022

ユーザーインターフェースの設計

イベントの処理


Responding to keyboard events
About keyboard events1003023

参照

Delphi にはキー入力をするために 3 つのイベントが用意されています。

OnKeyDown

OnKeyPress

OnKeyUp

これらのイベント用にイベントハンドラを作成して，実行時に入力するキーまたはキーの組み合わせに応答するようにできます。

メモ:	ショートカットキーまたはアクセラレータキー (メニューコマンドで指定するキーなど) を押したときアプリケーションが応答する場合は，イベントハンドラを作成する必要はありません。

キーボードイベントを処理する場合注意すべき点がいくつかあります。詳細は次の各トピックを参照してください。

キーボードイベントの処理順序	キー入力の処理方法	フォームへのキーボードイベントのリダイレクト


See also1003024

ユーザーイベントについて

アクセラレータキーの指定

TShiftState


Keyboard event processing order
Keyboard event processing order1003025

参照	例

Example

アプリケーションレベル (Application.OnMessage イベントと一緒に)

アプリケーションレベルではキー入力をインターセプトする必要はほとんどない。このレベルを使えることだけ覚えておくこと

ショートカットキーレベル

ショートカットキー (メニュー項目のプロパティとして指定するキーなど) を指定すると，キー入力はフォームがそれを認識する前にインターセプトされる

フォームレベル

フォームにはグローバルなキー入力イベントをプログラムできる KeyPreview プロパティが含まれている

コンポーネントレベル

コンポーネントレベルでキー入力イベントハンドラを作成すると，フォーカスがあるコンポーネントがキー入力をインターセプトする


See also1003026

キーボードイベントについて

キー入力の処理方法

フォームへのキーボードイベントのリダイレクト


Example1003027

次のコードはフォームの 2 つのボタンを使って，アプリケーションがキーボードイベントを処理する順序を示します。

初めてプログラムを実行し Alt+Ctrl を押すと，フォームが紫色になります。フォーカスがある Button1 がキー入力を処理するからです。Button1 がキー入力を処理しないように Button1 をクリックするかフォームの KeyPreview をオンに設定するため Button2 をクリックしてから Ctrl+Alt を再度押すと，フォームはアクアマリンになります。フォームがキー入力を処理するからです。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if (shift = ([ssAlt, ssCtrl])) then form1.color := clAqua;

end;

procedure TForm1.Button1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

 if (shift = ([ssAlt, ssCtrl])) then form1.color := clPurple;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

button1.enabled := false;

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

Form1.Keypreview := True;

end;


Processing keystrokes
Processing keystrokes1003028

参照	例

キーを入力すると必ず OnKeyDown イベントと OnKeyUp イベントが生成されます。通常の文字のキーを入力すると OnKeyPress イベントも生成されます。コードがすべてのキー入力を認識する必要はありませんが，キー入力イベントが処理される順番は理解していなくてはなりません。次の例を参照してください。

アプリケーションはイベントをいくつかのレベル (キーボードイベントの処理順序を参照) で認識できます。OnKeyPress は文字を 1 字返します。OnKeyDown と OnKeyUp は最後のキー入力時にコントロールキー (Alt，Ctrl，Shift キーなど) を押したかどうか示すパラメータを返します。

たとえば Shift+D を押すと，OnKeyDown，OnKeyPress，OnKeyUp のキー入力イベントが順に発生します。

KeyDown (Shift)

KeyDown (Shift+D)

KeyPress (D)

KeyUp (Shift+D)

KeyUp

キーをいくつか組み合わせて押すと，OnKeyDown イベントはその前の OnKeyDown のキーを次の OnKeyDown に渡します。これに対して OnKeyPress イベントは最後に押したキーを返すだけです。ただし OnKeyPress は d と D を押したときで異なる文字を返します。OnKeyDown と OnKeyUp の場合は大文字と小文字のアルファベットキーを区別しません。


See also1003029

キーボードイベントについて

キーボードイベントの処理順序

フォームへのキーボードイベントのリダイレクト


Example1003030

次のコードはリストボックスを使って，フォームの OnKeyUp，OnKeyDown，OnKeyPress の各キー入力イベントを処理する順序を表示します。押したキーを表示するのに Edit コンポーネントも使います。

メモ:	フォームに［デフォルト］ボタンと［キャンセル］ボタン (Default プロパティと Cancel プロパティがそれぞれ True に設定されているボタン) を加えると，これらのボタンが存在する場合キー入力 Escape と Enter がどのように処理されるかがわかります。

procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

Listbox1.Items.Add('Edit1.KeyDown'+ShortCutToText(ShortCut(Key, Shift)));

end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);

begin

Listbox1.Items.Add('Edit1.KeyPress'+ Key);

end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

Listbox1.Items.Add('Edit1.KeyUp'+ShortCutToText(ShortCut(Key, Shift)));

end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

Listbox1.Items.Add('Form1.KeyDown'+ShortCutToText(ShortCut(Key, Shift)));

end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

 Listbox1.Items.Add('Form1.KeyPress'+ Key);

end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

Listbox1.Items.Add('Form1.KeyUp'+ShortCutToText(ShortCut(Key, Shift)));

end;


Responding to the OnKeyPress event
Responding to the OnKeyPress event1003031

参照	例

REDUNDANT WITH CURRENT VCL

OnKeyPress イベントは 3 つのイベントの中で最も簡単です。つまり入力した文字を 1 字返すだけです。文字は ASCII 文字セットに含まれている文字でなくてはなりません。

OnKeyPress はキーの組み合わせを ASCII 文字 1 字と解釈します。たとえば OnKeyPress は Shift+A の結果 (大文字の A) を認識できますが 2 つのキーを押したことはわかりません。Shift キー以外の組み合わせは認識できません。ファンクションキーや非 ASCII 文字キー (Ctrl，Alt，Ins，Page Down など) も認識できません。

フォームの［デフォルト］ボタンまたは［キャンセル］ボタンは OnKeyPress イベントと OnKeyDown イベントのキー入力 Enter と Escape をインターセプトします (OnKeyDown で Alt と一緒に使う場合を除きます)。


See also1003032

キーボードイベントについて

キーボードイベントの処理順序

キー入力の処理方法

フォームへのキーボードイベントのリダイレクト


Example1003033

次のコードはキーボードイベントを処理する OnKeyPress と OnKeyDown のプログラミング方法を示します。

OnKeyPress イベントは Char 型のキーパラメータを含んでいます。どのキーを押したか調べるには，その文字を入力するだけでわかります。

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

case key of

'I': Panel1.Caption := 'Shift+I was pressed';

'c': Panel1.caption := 'c was pressed';

' ': Panel1.caption := 'the space bar was pressed';

end;

end;

OnKeyDown のキーパラメータは Word 型です。どのキーを押したか調べるには同等の仮想キーコードを参照しなくてはなりません。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

case key of

vk_Insert: Panel1.Caption := 'INS';

vk_Capital: Panel1.caption := 'CAP';

vk_Numlock: Panel1.caption := 'NumLock';

end;

end;


Responding to the OnKeyUp and OnKeyDown events

参照	例

アクティブなコントロールがキーイベントを受け取ったときに Shift，Ctrl，Alt のどれかが一緒に押されていることを認識する場合とファンクションキーなど ASCII 文字以外のキーを処理する場合は，OnKeyDown イベントと OnKeyUp イベントを使います。たとえば F1 キーは英数字を表示していないので OnKeyPress イベントは認識できません。See Responding To The OnKeyPress Event

どちらのキーイベントも押したキーの値を返しますが，OnKeyDown イベントの方が一般的に使われています。キーを押し下げて元に戻す間にバックグラウンド処理を開始する場合は OnKeyUp を使います。キーを押したままにすると，キーから指を離すまで繰り返し OnKeyDown イベントが返されます。指を離すと OnKeyUp イベントを 1 回返します。ゲームなどのプログラムでは，このような特定のキーボード対話が便利です。

メモ:	どのキーを押したか調べるため OnKeyDown または OnKeyUp を使う場合，仮想キーコードを使ってキーを指定しなくてはなりません。パラメータキーが Word 型だからです。たとえば次のイベントハンドラは Ins キーを押すとフォーム内のパネルに INS と表示します。Vk_Insert は Ins キーの仮想キーコードです。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if key = vk_Insert then Panel1.Caption := 'INS';

end;


See also1003034

キーボードイベントについて

キーボードイベントの処理順序

キー入力の処理方法

フォームへのキーボードイベントのリダイレクト


Example1003035

次の 2 つのイベントハンドラは Z キーを押すとグラフィックイメージを拡大し，Z キーから指を離すとグラフィックイメージを縮小して OnKeyDown イベントと OnKeyUp イベントに応答します。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if chr(Key) = 'Z' then Image1.Stretch := True;

end;

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if chr(Key) = 'Z' then image1.Stretch := False;

end;


Redirecting keyboard events to the form
Redirecting keyboard events to the form1003036

例

Set the KeyPreview property of a form to True.

フォームレベルでキーボードイベントを処理できます。キーボードイベントが発生したときにフォーカスを受け取るフォーム内のコンポーネントごとにイベントハンドラを作成する必要はありません。フォームはフォーカスがあるコンポーネントが受け取れるキー入力を受け取れます。KeyPreview を使えばコンポーネントごとにユニークなキーボードイベントハンドラを作成できます。

KeyPreview はコンポーネントレベルのキーボードハンドラを起動するときにフォームレベルのキーボードイベントハンドラを自動的に呼び出すのと似ています。コンポーネントはイベントを認識していますが，フォームの方が先にイベントを処理できます。たとえばキーをマッピングして，最初に押したキーではなくマップしたキーを ButtonKeyDown が受け取るようにする FormKeyDown のイベントハンドラを作成できます。


See also1003037

キーボードイベントについて

キーボードイベントの処理順序

キー入力の処理方法


Example1003038

次のコードはフォームの KeyPreview プロパティがキー入力をインターセプトする方法を示します。

フォーム上にボタンを割り当て，フォームの OnKeyDown イベント用に次のイベントハンドラを作成する

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

Shift: TShiftState);

begin

if (shift = ([ssAlt, ssCtrl])) then Form1.color := clAqua;

end;

アプリケーションを起動してから Alt+Ctrl を押す

何も起こらない。フォーカスがあるコントロールがキーボードイベントを受け取るからである。このボタンのキーボードイベントハンドラは作成していない

ボタンを無効にするかボタンのイベントハンドラにコードを作成しなくてはならない。フォームの KeyPreview を True に設定すると，コードを書き込まなくてもフォームレベルでキー入力をインターセプトできる

フォームの KeyPreview を True に設定し，プログラムを再度実行する。今度は Ctrl+Alt を押すとフォームがキー入力を受け取りフォームが薄い空色になる


Creating a Select File dialog box
Creating a Select File dialog box 1003039

1.	フォームに次のコントロールを割り当てます 。

DriveCombo1 という名前の DriveComboBox

DirList1 という名前の DirectoryListBox

FileEdit1 という名前の Edit コンポーネント

Filter1 という名前の FilterComboBox

FileList1 という名前の FileListBox

PathLabel という名前の Label コンポーネント

2.	DriveCombo1 を選択し DirList := DirList1 を設定します。

3.	DirList1 を選択します。DirLabel := PathLabel と FileList := FileList1 を設定します。

4.	Filter1 を選択します。FileList := FileList1 を設定し，Filter プロパティに必要な値を設定します 。

5.	FileList1 を選択します。FileEdit := FileEdit1 を設定します。複数のファイル名を選択したければ，MultiSelect := True を設定します。

6.	次の各イベント用にイベントハンドラをコーディングします。

Form の OnCreate イベント

Filter1 の OnChange イベント

DriveCombo1 の OnChange イベント

FileList1 の OnChange イベント


Event handler code for Form OnCreate event1003040

begin

FileList1.Mask := Filter1.Mask;

Filter1Change(Filter1);

PathLabel.Caption := DirList1.Directory;

end;


Event handler code for Filter1 OnChange event1003041

begin

FileEdit.Text := FileList1.Mask;

PathLabel.Caption := DirList1.Directory;

end;


Event handler code for DriveCombo1 Onchange Event1003042

begin

PathLabel.Caption := DirList1.Directory;

end;


Event handler code for FileList1 OnChange event1003043

begin

PathLabel.Caption := DirList1.Directory + '\' + FileList1.Filename;

end;


About the Timer component
About the Timer component1003044

TTimer リファレンス	コモンコンポーネントの使い方

目的

Timer コンポーネントは 1 回だけまたは指定した間隔で繰り返しイベントを発生させるのに使います。指定した時間にイベントを発生させるコードは Timer コンポーネントの OnTimer イベント内に作成します。

使い方

タイマーイベントを発生させるまでの経過時間を指定するには Interval プロパティを使う

時間を指定したイベントの発生を中断するには Timer コンポーネントの Enabled プロパティを False に設定する

スプラッシュ画面を表示する


Displaying a SplashScreen
Displaying a SplashScreen1003045

次の 2 つのイベントハンドラはアプリケーションのメインフォームが開く前にフォーム SplashScreen を表示してから閉じます。Form1 の interface 部で定数 Startup を宣言します。最初のイベントハンドラは Form1 の OnActivate イベントから SplashScreen の Show メソッドを呼び出します。

procedure TForm1.FormActivate(Sender: TObject);

begin

if Startup then

begin

Startup := False;

SplashScreen.Show;

end;

end;

SplashScreen には Timer コンポーネントが含まれており，その Interval プロパティは 3000 に設定されています。つまりそのフォームは 3 秒間表示されてから閉じます。フォームの Close メソッドは Timer コンポーネントの OnTimer イベントにアタッチされています。

procedure TForm2.Timer1Timer(Sender: TObject);

begin

Close;

end;


About the PaintBox component
About the PaintBox component1003046

TPaintBox リファレンス	コモンコンポーネントの使い方

目的

フォーム上の描画範囲を PaintBox で囲んだ長方形の領域に限定するのに使います。

使い方

PaintBox の描画表面にアクセスするには Canvas プロパティを使う

PaintBox のキャンバスに描画するには OnPaint イベント用のイベントハンドラに適切なコードを作成する


About the MediaPlayer component
About the MediaPlayer component1003047

参照	TMediaPlayer リファレンス

目的

MediaPlayer コンポーネントはアプリケーションがメディアプレーヤまたはレコーディングデバイス (CD-ROM プレーヤ，ビデオプレーヤ / レコーダ，MIDI シーケンサなど) を制御できるようにするのに使います。

MediaPlayer の使い方の決定

メディアプレーヤコンポーネントの使い方と構成方法は制御するデバイスの種類と，デバイスのすべての機能を使うか特定のものだけを使うかでほぼ決まります。

たとえばビデオカセットレコーダを制御しており，不注意でテープを消去することがないようにするには，MediaPlayer コンポーネントの Record セグメントを使用不可つまり非表示にできます。

メディアにコンパクトディスクのようにトラックがあるならば，MediaPlayer の Rewind 機能を使う必要がありません。ビデオテープまたはディジタルオーディオテープ (DAT) デバイスでは Rewind 機能が必要です。

コンポーネントの機能を制御する使い方

MediaPlayer コンポーネント上の各ボタンセグメントを表示または非表示にするには VisibleButtons プロパティを使う

 MediaPlayer コンポーネント上の各セグメントを使用可能または使用不可にするには EnabledButtons プロパティを使う

再生または記録の前にメディアの最後の位置にある場合，デバイスが自動的に巻き戻すかどうか指定するには，AutoRewind プロパティを使う

他のコンポーネントまたはアプリケーションがそのデバイスにアクセスできるかどうか調べるには Shareable プロパティを使う

デバイスのアクセスを制御する使い方

MediaPlayer コンポーネントが制御するデバイスの種類を指定または変更するには DeviceType プロパティを使う

現在ロードしているメディア内の開始位置を指定または変更するには Start プロパティを使う

メディアの現在の位置を指定または変更するには Position プロパティを使う

メディア上の情報にアクセスする使い方

再生または記録するメディアファイルを指定または変更するには FileName プロパティを使う

カレントデバイスの ID を調べるには，実行時のみで読み出し専用のプロパティ DeviceID を使う

現在ロードしているメディア内で再生または記録を開始する位置を指定するには，実行時のみで読み出し専用のプロパティ StartPos を使う

オープンしているマルチメディアデバイスのトラック数を調べるには，実行時のみで読み出し専用のプロパティ Tracks を使う

トラック長を調べるには，現在の TrackNum インデックスの実行時のみで読み出し専用のプロパティ TrackLength を使う

トラックの位置を調べるには，現在の TrackNum インデックスの実行時のみで読み出し専用のプロパティ TrackPosition を使う

デバイス操作を制御する使い方

MediaPlayer コンポーネントはメディアプレーヤまたはレコーディングデバイスの操作を制御するメソッドを持っています。これらのメソッドにはコンポーネントのボタンセグメントに対応しているもの (アスタリスク (*) が付いているもの) があります。これらのメソッドはオプションでプログラムコードでも呼び出せます。

デバイスを制御するメソッドをアルファベット順に次に示します。

*Back	*Pause	Rewind

Close	PauseOnly	*StartRecording

*Eject	*Play	*Step

*Next	*Previous	*Stop

Open	Resume


See also1003048

コモンコンポーネントの使い方

Also see Windows Multimedia Reference


About the OLEContainer component
About the OLEContainer component1003049

TOLEContainer リファレンス	Using OLE Automation

目的

OLEContainer コンポーネントはアプリケーションが OLE サーバーオブジェクトをリンクし埋め込むのに使います。

OLE コンテナのオブジェクトをアクティブにすると，OLE サーバーアプリケーションに制御が渡され，コンテナアプリケーションからサーバーアプリケーションのすべての機能にアクセスできます。


About the DDEClientConv component
About the DDEClientConv component1003050

TDDEClientConv リファレンス	DDE について

目的

DDE is an older technology for interapplication communication.  For new projects that need not access legacy DDE server applications, you should instead use OLE Automation.

DDEClientConv コンポーネントはアプリケーションが他のアプリケーションを使って DDE 対話を設定できるようにするのに使います。フォームにこのコンポーネントを割り当てると，アプリケーションは DDE クライアントになります。

アプリケーションを完全な DDE クライアントにするには，このコンポーネントと DDEClientItem コンポーネントを一緒に使います。

使い方

DDE を使った他のアプリケーションの制御	DDE クライアントとのリンクの設定	DDE サーバーとのリンクの設定	データのポーク	DDE クライアントアプリケーションの作成	DDE 対話のトピックを指定するには DDETopic プロパティを使う

DDE サーバーアプリケーションを指定するには DDEService プロパティを使うthe server application name is usually but not always the executable.

DDE サーバーアプリケーションの実行可能名を指定するには ServiceApplication プロパティを使う

DDE サーバーアプリケーションへリンクするときに接続の種類を定義するには ConnectMode プロパティを使う

サーバーアプリケーションから転送するテキストデータの文字にフィルタをかけるには FormatChars プロパティを使う


About the DDEClientItem component
About the DDEClientItem component1003051

TDDEClientItem リファレンス	DDE について

目的

DDE is an older technology for interapplication communication.  For new projects that need not access legacy DDE server applications, you should instead use OLE Automation.

DDEClientItem コンポーネントは DDE 対話の項目を定義するのに使います。アプリケーションを DDE クライアントにするには，このコンポーネントと DDEClientConv コンポーネントを一緒に使います。If you will need only one item, the DDEClientConv is not necessary.

使い方

DDE を使った他のアプリケーションの制御	DDE クライアントとのリンクの設定	DDE サーバーとのリンクの設定	データのポーク	DDE クライアントアプリケーションの作成	DDE クライアント対話コンポーネントを指定するには DDEConv プロパティを使う

DDE 対話の項目を指定するには DDEItem を使う

To find out what the DDE Server sent, read the Lines property.


About the DDEServerConv component
About the DDEServerConv component1003052

TDDEServerConv リファレンス	DDE について

目的

DDE is an older technology for interapplication communication.  For new projects that need not support legacy DDE client applications, you should instead use OLE Automation.

DDEServerConv コンポーネントはアプリケーションが他のアプリケーションと DDE 対話を設定できるようにするのに使います。フォームにこのコンポーネントを割り当てると，アプリケーションは DDE サーバーになります。

アプリケーションを完全な DDE サーバーにするには，このコンポーネントと DDEServerItem コンポーネントを一緒に使います。

使い方

DDE サーバーアプリケーションの作成	DDE クライアントとのリンクの設定	DDE サーバーとのリンクの設定


About the DDEServerItem component
About the DDEServerItem component1003053

TDDEServerItem リファレンス	DDE について

目的

DDE is an older technology for interapplication communication.  For new projects that need not support DDE client applications, you should instead use OLE Automation.

DDEServerItem コンポーネントは他のアプリケーションとの DDE 対話のトピックを決めるのに使います。

アプリケーションを DDE サーバーにするには，このコンポーネントと DDEServerConv コンポーネントを一緒に使います。

使い方

DDE サーバーアプリケーションの作成	DDE クライアントとのリンクの設定	DDE サーバーとのリンクの設定DDE サーバー対話コンポーネントを指定するには ServerConv プロパティを使う


データベースエクスプローラ
データベースエクスプローラ1005001

データベースエクスプローラを使うと，アプリケーション開発中にリモートサーバーへの持続的な接続を維持でき，また BDE エリアスやメタデータオブジェクトを扱うことができます。データベースエクスプローラを使って以下に示すものを作成，表示，および変更できます。

BDE エリアス

テーブル，ビュー，トリガー，ストアドプロシージャなどのメタデータ

データベースエクスプローラの［データベース］ペインには定義されているすべての有効なエリアスが表示されます。エリアスを選択するとそのエリアスの定義が表示されます。

エリアスで指定されるデータベースに接続するには

1.	［データベース］ペインでエリアスを選択します。

2.	次のいずれかを行います。

［オブジェクト(O)｜開く(O)］を選択します。

データベースエクスプローラのスピードメニューから［開く(O)］を選択します。

データベースに接続すると，左ペインのアイコンが緑色の枠で囲まれます。

データベースの表示を展開するには

［データベース］ペインで，表示したいエリアスの横の［+］をクリックします。アイコンの下にネイティブサーバーオブジェクトが表示されます。

データベースに接続すると，そのデータベースに対する SQL 操作を実行できるようになります。

SQL 操作を実行するには

1.	［SQL 文の入力］タブを選択します。

2.	文領域に SQL 文を入力します。

3.	問い合わせの実行ボタンをクリックします。

SQL 文が実行され，その結果がテーブルグリッドに表示されます。

データベースエクスプローラのヘルプメニューを開き，メニューでコマンドで選択すると，詳しい情報が表示されます。


ブレークポイントの設定ダイアログボックス
ブレークポイントの設定ダイアログボックス1007001

参照

［ブレークポイントの設定］ダイアログボックスは，ブレークポイントを追加または既存のブレークポイントを変更するために使います。ブレークポイントはコードエディタとブレークポイント一覧ウィンドウに表示されます。

ブレークポイントを設定することによって，次のいずれかの状況でプログラムの実行に割り込みをかけることができます。

指定したコード行が実行された場合

コード行の実行時に指定した条件が発生した場合

条件または行番号を特定の回数だけ実行した場合

このダイアログボックスを使ってブレークポイントを発生させる場所を指定します。

行番号に基づいてブレークポイントを作成するには，［ファイル名(F)］と［行番号(L)］に値を入力する

条件に基づいてブレークポイントを作成するには，［ファイル名(F)］，［行番号(L)］，および［ブレーク条件(C)］に値を入力する

行が実行される回数に基づいてブレークポイントを作成するには，［ファイル名(F)］，［行番号(L)］，および［パスカウント(P)］に値を入力する

コード行の実行時に条件が発生した回数に基づいてブレークポイントを作成するには，［ファイル名(F)］，［行番号(L)］，［ブレーク条件(C)］，および［パスカウント(P)］に値を入力する

［ブレークポイントの設定］ダイアログボックスを開くには

次のいずれかの操作を行います。

［実行(R)｜ブレークポイントの追加(B)］を選択する

ブレークポイント一覧のスピードメニューで［追加(A)］を選択する

ブレークポイント一覧ウィンドウで既存のブレークポイントを右クリックし，ブレークポイント一覧のスピードメニューから［プロパティ(R)］を選択する

ダイアログボックスオプション

［ファイル名(F)］

ブレークポイントを設定するプログラムファイルを設定または変更します。ブレークポイントを設定するプログラムファイルの名前を入力します。

［行番号(L)］

ブレークポイントを設定する行番号を設定または変更します。ブレークポイントを設定する行番号を入力または変更します。

［ブレーク条件(C)］

ブレークポイントが検出されるたびに評価する条件式を指定します。式が True と評価されると，プログラムの実行は停止します。プログラムの実行を停止するための条件式を入力します。

条件式には有効な言語式を入力できます。ただし，式に含めるすべてのシンボルはブレークポイント位置からアクセス可能でなくてはならず，式に関数呼び出しを含めることはできません。

［パスカウント(P)］

指定した回数の通過後，特定の行番号でプログラムの実行を停止します。パスカウントを入力します。

ブレークポイントを含む行が検出されるたびにパスカウントがデクリメントされます。パスカウントが 1 になったとき，プログラムの実行が停止します。

パスカウントは 1 回の通過ごとにデクリメントされるため，パスカウントを使って何回目のループで失敗したかを判定できます。パスカウントを最大ループ回数に設定してプログラムを実行すれば，プログラムが失敗したときにパスカウントを調べることによってループの繰り返し回数を計算できます。

パスカウントを条件とともに使う場合，条件式が n 回目に真になったとき，プログラムの実行が停止します。Delphi は条件式が真の場合にのみパスカウントをデクリメントします。


参照1007002

ブレークポイントの使い方

ブレークポイント一覧ウィンドウ

ブレークポイント一覧ウィンドウのタスク


監視式のプロパティダイアログボックス
監視式のプロパティダイアログボックス1007003

参照

［監視式のプロパティ］ダイアログボックスは，監視式を追加したり，既存の監視式のプロパティを変更するために使います。監視式は監視式一覧ウィンドウに表示されます。

監視式のプロパティを変更するほかに，監視式の値を変更できます。監視式の値を変更するには，［評価/変更］ダイアログボックスを使います。

［監視式のプロパティ］ダイアログボックスを開くには

次のいずれかの操作を実行します。

コードエディタスピードメニューで［この単語を監視式に追加(A)］を選択する

［実行(R)｜監視式の追加(W)］を選択する

監視式一覧スピードメニューで［監視式の追加(A)］を選択する

監視式一覧ウィンドウで既存の監視式を右クリックし，監視式一覧スピードメニューで［監視式の編集(E)］を選択する

ダイアログボックスオプション

［監視する式(E)］

監視する式を指定します。監視したい式を入力または編集します。ドロップダウンボタンを使うと，前に選択した式のヒストリから選択できます。

［繰り返し回数(U)］

監視式がデータ要素を表す場合は，繰り返し回数を指定します。監視式が配列を表す場合は，配列内の要素数を指定します。繰り返す回数を入力します。

配列を監視するため繰り返し回数として要素数を指定する場合，監視式一覧ウィンドウには配列内のすべての要素の値が表示されます。

［桁数(G)］

浮動小数点式の監視式の値の有効桁数を指定します。桁数を入力します。

［有効(N)］

監視式を有効または無効にします。監視式を無効にすると，現在のプログラム実行でその監視式は非表示になります。監視式を無効にした場合，監視式の設定は定義されたまま残りますが，評価はされません。

監視式を無効にすると，プログラム内をステップ実行または実行するとき監視式が監視されないため，デバッガの処理効率が向上します。設定した監視式は，デフォルトでは有効になります。

監視式の表示形式を設定するには

表示形式を指定するラジオボタンを選択します。

詳細については監視式プロパティの形式の種類を参照してください。


参照1007004

［評価/変更］ダイアログボックス


監視式プロパティの形式の種類
監視式プロパティの形式の種類1007005

参照

デフォルトでは，監視式の結果は式のデータ型と一致する形式で表示されます。たとえば，整数値は通常 10 進形式で表示されます。［監視式のプロパティ］ダイアログボックスで整数型の式に対して［16 進整数(X)］ラジオボタンを選択した場合，表示形式は 10 進から 16 進に変わります。

［文字(C)］

ASCII コードの 0 から 31 までの特殊文字も表示します。デフォルトでは，これらの文字は # が付いて表示されます。この形式タイプは文字と文字列に作用します。

［文字列(S)］

ASCII コードの 0 から 31 までの文字は # を付けて表示します。メモリダンプを変更する目的でのみ使います。この形式タイプは文字と文字列に作用します。

［10 進整数(D)］

整数値を 10 進形式で表示します。データ構造内の整数も含みます。この形式タイプは整数に作用します。

［16 進整数(X)］

整数値を $ プレフィックス付きの 16 進形式で表示します。データ構造内の整数も含みます。この形式タイプは整数に作用します。

［序数(O)］

順序型を整数値として表示します。

［ポインタ(P)］

ポインタをセグメント:オフセット表記で表し，ポインタが指し示すアドレスの内容を表示します。セグメントが位置するメモリの領域と，オフセットアドレス位置の変数名がわかります。この形式タイプはポインタに作用します。

［構造体(R)］

フィールド名と値の両方を表示します。たとえば，(1,10,5) ではなく (X:1;Y:10;Z:5) のように表示します。

［デフォルト(L)］

式のデータ型と一致する表示形式で結果を表示します。この形式タイプはすべてに作用します。

［メモリダンプ(M)］

指定した式のアドレス位置から始まるサイズのバイトを表示します。デフォルトでは，各バイトは 2 桁の 16 進数で表します。バイト形式を変更するには，文字，10 進，16 進，文字列のオプションとともにメモリダンプを使います。


参照1007006

監視式

監視式一覧ウィンドウ

監視式一覧ウィンドウのタスク


評価/変更ダイアログボックス
評価/変更ダイアログボックス1007007

参照

［評価/変更］ダイアログボックスは，既存の式またはプロパティの値を評価または変更するために使います。次のものを含む場合を除き，有効な言語式であれば評価することができます。

現在の実行ポイントからアクセスできないローカル変数または静的変数

関数呼び出し

デバッグセッション中にデータ構造の変数や項目の値を変更できます。デバッグセッションの間にデータ項目の値を変更することによって想定されるさまざまなエラーについてテストしたり，異なる状況下でコードセクションがどのように動作するかを確認したりできます。

デバッガを使ってデータ項目の値を変更する場合，変更はその特定のプログラム実行に対してのみ有効です。［評価/変更］ダイアログボックスで変更した内容は，ソースコードやコンパイルされたプログラムには影響しません。変更を永続的にするには，コードエディタでソースコードを変更した後，プログラムをコンパイルし直さなくてはなりません。

値 (特にポインタ値と配列インデックス) の変更は，他の変数やデータ構造を上書きする可能性があるため，好ましくない影響をもたらす危険があります。デバッガでプログラム値を変更する場合には注意してください。

プログラムのデータ値を変更する場合は次の点に注意してください。

個々の変数または配列やデータ構造の要素を変更できるが，配列またはデータ構造全体の内容は変更できない

［新しい値(N)］ボックスの式の評価結果はそれを代入する変数と代入互換性がなくてはならない。代入によってコンパイルエラーまたは実行時エラーが発生した場合，変更値が有効でないと考えられる

関数に渡された型なし引数を直接変更することはできないが，型キャストして新しい値を割り当てられる

値の形式

式を評価するとき，式の現在の値がダイアログボックスの［結果(R)］フィールドに表示されます。必要に応じてこの結果の形式を変更できます。［評価する式(E)］編集ボックスに入力した式の後にさらにカンマと形式を続けます。詳細については形式指定子の評価と変更を参照してください。

［評価/変更］ダイアログボックスを開くには

次のどちらかの操作を実行します。

［実行(R)｜評価/変更(V)］を選択する

コードエディタスピードメニューで［評価/変更(E)］を選択する

ダイアログボックスオプション

［評価する式(E)］

評価または変更する変数，フィールド，配列，オブジェクトのいずれかを指定します。評価または変更する変数，フィールド，配列，オブジェクトを入力します。

デフォルトでは，コードエディタ内のカーソル位置にある語が［評価する式(E)］編集ボックスに表示されます。この式を受け入れるか，別の式を入力するか，あるいは前に評価した式のヒストリリストから式を選択できます。

［結果(R)］

［評価(V)］または［変更(M)］を選択すると，［評価する式(E)］テキストボックスで指定した項目の値が表示されます。

［新しい値(N)］

［評価する式(E)］編集ボックスで指定した項目に新しい値を割り当てます。値を変更したい場合は項目に新しい値を入力します。

［評価(V)］

［評価する式(E)］編集ボックスの式を評価し，値を［結果(R)］編集ボックスに表示します。

［変更(M)］

［新しい値(N)］編集ボックスの値を使って［評価する式(E)］編集ボックスの式の値を変更します。


参照1007008

式の評価と変更


形式指定子の評価と変更
形式指定子の評価と変更1007009

参照

デフォルトでは，式のデータ型と一致する形式で結果が表示されます。たとえば，整数値は通常 10 進形式で表示されます。表示形式を変更するには，式の後にカンマ (,) を入力し，さらに形式指定子を続けます。

例

［評価する式(E)］ボックスに整数値 z があり，結果を 16 進で表示したい場合を想定します。

1.	［評価する式(E)］ボックスに z,h と入力します。

2.	［評価(V)］を選択します。

形式指定子

次の表は評価/変更の形式指定子を示します。

指定子	対象の型	説明

,C	文字，文字列	文字。ASCII コードの 0 から 31 までの文字は Pascal の #nn の表記書式で表示する

,S	文字，文字列	文字列。ASCII コードの 0 から 31 までの文字は Pascal の #nn の表記書式で表示する

,D	10 進整数	整数値を 10 進形式で表示する。データ構造内の整数も含む

,H か ,X	16 進整数	整数値を $ プレフィックス付きの 16 進数で表示する。データ構造内の整数値も含む

,Fn	浮動小数点	浮動小数点。有効 n 桁を表示する。n は 2 から 18 である。たとえば，浮動小数点数値の最初の 4 桁を表示するには ,F4 と入力する。n を指定しない場合，デフォルトは 11 になる

,P	ポインタ	ポインタを 32 ビットアドレスとして，ポインタが指し示すアドレスについての補足情報とともに表示する。ポインタが位置するメモリの領域と，オフセットアドレス位置に変数があればその名前が表示される

,R	レコード，クラス，

オブジェクト	レコード/クラス/オブジェクト。フィールド名と値の両方を表示する。たとえば (1,10,5) の代わりに (X:1;Y:10;Z:5) のように表示する

,nM	すべて	メモリダンプ。指定した式のアドレスから始まる n バイトを表示する。たとえば，メモリアドレス位置から始まる最初の 4 バイトを表示するには ,4M と入力する。n を指定しない場合，変数の型のサイズを示すバイト数になる。デフォルトでは，各バイトは 2 桁の 16 進数で表す。バイトの形式を変更するには，C，D，H，S の形式指定子とともにメモリダンプを使う


参照1007010

［評価/変更］ダイアログボックス


デバッガのウィンドウ
デバッガのウィンドウ1008001

参照

統合デバッガでは次のウィンドウを使って作業できます。

ブレークポイント一覧ウィンドウ	現在のソースコード内に設定されているすべてのブレークポイントを表示して追加，変更，削除します。

監視式一覧ウィンドウ	現在のソースコードに設定されているすべての監視式を表示して追加，変更，削除します。

呼び出し履歴ウィンドウ	関数呼び出しのシーケンスと各関数呼び出しに渡された引数を表示します。


参照1008002

デバッガのメニュー

デバッガのスピードメニュー


デバッガのメニュー
デバッガのメニュー1008003

参照

統合デバッガでは次のメニュー項目を使って作業できます。

表示メニュー

表示(V)｜ブレークポイント(B)

表示(V)｜呼び出し履歴(C)

表示(V)｜監視式(W)

コンパイルメニュー

プロジェクト(P)｜コンパイル(C)

実行メニュー


参照1008004

デバッガのウィンドウ

デバッガのスピードメニュー


デバッガのスピードメニュー
デバッガのスピードメニュー1008005

参照

統合デバッガでは次のスピードメニューを使って作業できます。

ブレークポイント一覧ウィンドウスピードメニュー

監視式一覧ウィンドウコンテキストメニュー

呼び出し履歴ウィンドウコンテキストメニュー

コードエディタスピードメニューでは次のコマンドを使えます。

ブレークポイントの設定(K)

カーソル位置まで実行(U)

評価/変更(E)

この単語を監視式に追加(A)


参照1008006

デバッガのウィンドウ

デバッガのメニュー


参照1008007

デバッガの処理


ブレークポイントウィンドウ
ブレークポイント一覧ウィンドウ1008008

参照

ブレークポイント一覧ウィンドウには現在のブレークポイントのリストが表示され，ブレークポイントを追加，編集，削除したり，有効と無効を切り替えたりできます。

ブレークポイントとはプログラム内で実行を一時的に停止する場所を指します。デバッガがブレークポイントに到達すると，プログラムは一時停止します。コード内にはいくつでもブレークポイントを指定できます。

ブレークポイントウィンドウを表示するには［表示(V)｜ブレークポイント(B)］を選択する

次の図は一般的なブレークポイントウィンドウの図です。

この図は次のことを示しています。

2 つのブレークポイントを含むファイルは Fontlist.pas である

Fontlist.pas の行番号 55 と 74 にブレークポイントが含まれる

55 行のブレークポイントは条件ブレークポイントである

ブレークポイントの通過回数はどちらもゼロである

ブレークポイント一覧ウィンドウにはすべてのブレークポイントがファイル名と行番号によって示されます。さらに，各ブレークポイントにはそのブレークポイントに指定された条件と通過回数も示されます。ブレークポイントが無効または不当な場合，そのブレークポイントはブレークポイント一覧ウィンドウ内に淡色表示されます。

ブレークポイントウィンドウを使うと，ソースファイル内をくまなく検索しなくても，すべてのブレークポイントを表示して保持できます。ブレークポイントウィンドウのスピードメニューのコマンドを使うとブレークポイント位置のコードを表示したり編集したりできます。


参照1008009

デバッガのウィンドウ

統合デバッガについて

ブレークポイントの使い方

ブレークポイント一覧ウィンドウの操作


監視式一覧ウィンドウ
監視式一覧ウィンドウ1008010

参照

監視式一覧ウィンドウには監視式の現在の値が表示され，監視式を追加，編集，削除したり，有効と無効を切り替えたりできます。

監視式はプログラムの実行中に変化する変数や式の値を監視します。プログラムを実行するとき，監視式に含まれる変数の値をプログラムが更新すると，監視式の値が変化します。

監視式一覧ウィンドウを表示するには［表示(V)｜監視式(W)］を選択する

次の図は一般的な監視式ウィンドウの図です。

この図は次のことを示しています。

i の値は 5 である

max の値は 13.55 である

x の値は 20 である

y の値は 0 である

監視式内の変数のいずれかが定義されていない場所に実行ポイントが移動すると，監視式全体が未定義になります。監視式の評価可能な場所に実行ポイントが戻ると，監視式ウィンドウに監視式の現在の値が再び表示されます。


参照1008011

デバッガのウィンドウ

統合デバッガについて

監視式

監視式ウィンドウの操作


呼び出し履歴ウィンドウ
呼び出し履歴ウィンドウ1008012

参照

呼び出し履歴ウィンドウにはプログラムが現在の位置に到達するまでの関数呼び出しと各関数呼び出しに渡された引数が表示されます。

呼び出し履歴ウィンドウを表示するには［表示(V)｜呼び出し履歴(C)］を選択する

次の図は一般的な呼び出し履歴ウィンドウの図です。

呼び出し履歴ウィンドウの最上部には，プログラムが最後に呼び出した関数が表示されます。この下にはその前に呼び出した関数が表示されます。関数のリストは前にさかのぼるように続き，プログラム内で最初に呼び出した関数がリストの一番下に表示されます。ウィンドウ内の各関数リストの後には呼び出しの際に渡された引数が示されます。

呼び出し履歴ウィンドウには現在ロードされているモジュールの関数だけが一覧表示されます。


参照1008013

デバッガのウィンドウ

統合デバッガについて

関数呼び出しの表示


デバッガの処理
デバッガの処理1008014

参照

次の各トピックではデバッガの処理の概要を参照できます。

一般的なデバッグ処理

デバッガの有効化

デバッグ情報の生成

コマンドライン引数の指定

デバッグセッションの開始

ブレークポイントと実行ポイントの色のカスタマイズ

プログラム実行の制御

コードのステップ実行

ブレークポイントに対する操作

ブレークポイントの設定

ブレークポイントの検索

ブレークポイントの無効化と有効化

ブレークポイントの削除

ブレークポイントプロパティの変更

監視式に対する操作

監視式

監視式の無効化

監視式の削除

データ値の調査と変更

式の評価と変更

関数呼び出しに対する操作

関数呼び出しの表示

例外処理

デバッガでの例外処理


参照1008015

統合デバッガについて


ブレークポイントウィンドウの操作
ブレークポイントウィンドウの操作1008016

参照

ブレークポイントウィンドウは次の操作に使えます。

ブレークポイントの設定

ブレークポイントの検索

ブレークポイントの無効化と有効化

ブレークポイントの削除

ブレークポイントプロパティの変更


参照1008017

ブレークポイントの使い方

ブレークポイントウィンドウ

デバッガの処理


監視式ウィンドウの操作
監視式ウィンドウの操作1008018

参照

監視式ウィンドウは次の操作に使えます。

監視式

監視式の無効化

監視式の削除


参照1008019

監視式

監視式ウィンドウ


Decision Query Editor dialog box
Decision Query Editor dialog box1009001

The Decision Query Editor dialog box defines queries for the active decision query component. This dialog box specifies the database, tables, available fields, dimensions, and summaries for decision cubes bound to the decision query. It also displays the defined query in ANSI-92 SQL syntax.

To display the Decision Query Editor dialog box, apply a decision query component to a form, then right-click and choose Decision Query Editor from the menu.

Dialog box options

Dimensions/Summaries tab

Specifies the database, tables, available fields, dimensions, and summaries for decision cubes bound to the decision query.

SQL Query tab

Displays the defined query in ANSI-92 SQL syntax. You can edit the query by editing the ANSI-92 SQL statements.

Query Builder button

Displays the Visual Query Builder to select and join data tables.


Dimensions/Summaries tab (Decision Query editor)
Dimensions/Summaries tab (Decision Query editor)1009002

Use this tab of the Decision Query Editor dialog box to define queries for the active decision query component. This tab specifies the database, tables, available fields, dimensions, and summaries for decision cubes bound to the decision query.

To display the Decision Query Editor dialog box, apply a decision query component to a form, then right-click and choose Decision Query Editor from the menu. Then, click the Dimension/Summaries tab if it isn't already visible.

To display a text version of the defined query, click the SQL Query tab.

Dialog box options

List Of Available Fields

Fields available for use in the decision query. If you're using more than one table and need to create a join, you can click the Query Builder button to launch the Visual Query Builder.

All Fields/Query Fields button

Toggles between displaying all fields in the selected table and only fields selected by the active query.

Dimensions

Lists fields selected as decision cube dimensions. To add a field to the Dimensions list, select a field in the List Of Available Fields, then click the right-arrow. To remove a field from the Dimensions list, select it in the list, then click the left-arrow.

Summaries

Lists fields selected as decision cube summaries. To add a field to the Summaries list, select a field in the List Of Available Fields, then click the right-arrow. To remove a field from the Summaries list, select it in the list, then click the left-arrow.

Table

Shows the active table from those included in the active database. You can select a different table from this dropdown list.

Database

Shows the active database from those included in the query. You can select a different database from this dropdown list.


SQL Query tab (Decision Query editor)
SQL Query tab (Decision Query editor)1009003

Use this tab of the Decision Query Editor dialog box to display SQL queries for the active decision query component.

If a query hasn't yet been defined, you can enter one directly in ANSI-92 SQL. Or, you can define it visually by selecting a database, tables, and fields on the Dimensions/Summaries tab.

To display the Decision Query Editor dialog box, apply a decision query component to a form, then right-click and choose Decision Query Editor from the menu. Then, click the SQL Query tab.

Dialog box options

Query Text

Displays SQL statements that define the current decision query. The defined query apears in ANSI-92 SQL syntax. You can edit the query directly by editing the ANSI-92 SQL statements; they are automatically converted to and from any appropriate dialect used to communicate with the server.

Edit Query/Edit Done button

When the Edit Query button is active, text appears in the Query Text window. You can type over it to edit it.

When you begin typing, button text changes to Edit Done. Click the button when your edit is complete. You can click Cancel Edit to restore the original query text.

Cancel Edit button

Cancels the current text edit and restores the original query.


Decision Cube Editor dialog box
Decision Cube Editor dialog box1009004

The Decision Cube Editor dialog box defines active dimensions and summaries for the active decision cube component. These settings are reflected in decision pivots bound to the decision cube.

To display the Decision Cube Editor dialog box, apply a decision cube component to a form, bind it to a decision query, then right-click the decision cube and choose Decision Cube Editor from the menu.

Dialog box options

Dimension Settings tab

Specifies the display name, type, active type, format, grouping, and initial value for fields supplied to the decision cube from the decision query component.

Memory Control tab

Displays the following settings for memory protection:

Decision cube dimension, summary, and cell maximums

Designer data display choices


Dimension Settings tab (Decision Cube editor)
Dimension Settings tab (Decision Cube editor)1009005

Use this tab of the Decision Cube Editor dialog box to specify the display name, type, active type, format, grouping, and initial value for fields supplied to the decision cube from the decision query component.

To display the Decision Cube Editor dialog box, apply a decision cube component to a form, bind it to a decision query, then right-click the decision cube and choose Decision Cube Editor from the menu. Then, click the Dimension Settings tab if it isn't already visible.

Dialog box options

Available Fields

Fields supplied to the decision cube component by the decision query component. When a field in the list is highlighted, its settings appear in the text boxes and lists on the right side of the dialog box.

Display Name

The name to appear in decision pivot, decision grid, and decision graph labels for the highlighted field.

Type

Whether the highlighted field is a dimension or a summary (for information only, not editable).

Active Type

When the information for the highlighted field is loaded: As Needed, when required for display; Active, all the time; Inactive, never.

Format

The Delphi format string that describes how to display values for the highlighted field.

Grouping

Whether to display all values or ranges of values. Use None to display all values. Use Year, Quarter, or Month to display a range of dates. Use Single Value for a single-dimension display. If custom ranges have been added by an application developer, they also appear in the list.

Initial Value

The starting value for a date or custom range, or the single value to display.


Memory Control tab (Decision Cube editor)
Memory Control tab (Decision Cube editor)1009006

Use this tab of the Decision Cube Editor dialog box to change the following settings for memory protection:

Decision cube dimension, summary, and cell maximums

Designer data display choices

To display the Decision Cube Editor dialog box, apply a decision cube component to a form, bind it to a decision query, then right-click the decision cube and choose Decision Cube Editor from the menu. Then, click the Memory Control tab.

Dialog box options

Cube Maximums

Sets maximums and displays current values for decision cube dimensions, summaries, and cells.

Maximum

Sets the maximum allowable dimensions, summaries, and cells for the selected decision cube. The lower the number, the less memory is used

Current

The current number of dimensions, summaries, and cells in use by the decision cube (for information only, not editable).

Active+Needed

The number of dimensions and summaries that have Active Type set to Active or As Needed on the Dimension Settings tab of the Decision Cube Editor dialog box, and the number of cells required to display them (for information only, not editable).

Active

The number of dimensions and summaries that have Active Type set to Active on the Dimension Settings tab of the Decision Cube Editor dialog box, and the number of cells required to display them (for information only, not editable).

Get Cell Counts button

When clicked, runs a query to estimate the number of cells used.

Designer Data Options

Saves time and memory by displaying only the specified data at design time.

Display Dimension Names

When checked, displays only dimension and summary names at design time. No values appear.

Display Names And Values

When checked, displays dimension and summary names and values at design time. No totals appear.

Display Names, Values, And Totals

When checked, displays dimension and summary names, values, and totals at design time.

Run Time Display Only

When checked, displays dimension and summary names, values, and totals only at run time. None of this data appears at design time.


コードエディタウィンドウ
コードエディタウィンドウ1010001

参照

コードエディタウィンドウにはコードエディタページが必ず 1 ページ以上あります。ページを含まないコードエディタウィンドウはありえません。つまり，コードエディタウィンドウの最後のページを閉じるとコードエディタウィンドウが閉じます。

1 つのコードエディタウィンドウで複数のファイルを開くことができます。ファイルごとに新しいページが開き，それぞれのページがウィンドウ上部のタブで表されます。たとえば，プロジェクトを開くと，そのプロジェクトがウィンドウの最初のタブになります。ユニットファイルなどのファイルを開くごとに，それぞれのファイルが続けてタブで表されます。

別のウィンドウを開くことで，コードエディタの任意のページのコピーを開くことができます。

コードエディタウィンドウを開くには

次のどちらかの操作を行います。

ファイルを開く

［表示(V)｜別の編集ウィンドウを開く(E)］を選択する

[別の編集ウィンドウを開く(E)] コマンドを使うと，コードエディタの現在のページのコピーが開きます。

変更したコードのページを閉じると，ファイルを保存していない場合，ファイルを保存するか確認されます。［はい(Y)］ボタンを押すとファイル名を入力するための［名前を付けて保存］ダイアログボックスが開きます。


参照1010002

フォームへのコンポーネントの追加

コードエディタの操作


コードエディタのしくみ
コードエディタのしくみ1010003

参照

フォームにコンポーネントを追加すると，コンポーネントのインスタンス変数 (フィールド) が生成され，そのインスタンス変数がフォームの型宣言に追加されます。例として，空白フォームにプッシュボタンコンポーネントを追加した場合のコードを次に示します。

type

  TForm1 = class(TForm)

    Button1: TButton;

  end;

プッシュボタンを追加すると，フォームの型宣言 (TForm1 = class(TForm)) にボタン自体のフィールド (Button1: TButton;) が追加されます。現在のプロジェクトでも新しいプロジェクトでも，コードエディタで同様にコードが追加されるのを確認できます。

コードが追加されるのをコードエディタで確認するには

1.	フォームのタイトルバーをドラッグしてコードエディタ全体が見えるようにします。

2.	型宣言部の位置までコードエディタ内をスクロールします。

3.	コードエディタの中で何が起きるか注目しながらフォームにコンポーネントを追加します。

メモ:	Delphi が生成するコードは編集しないでください。編集するのは自分で作成したコードだけにしてください。


参照1010004

フォームへのコンポーネントの追加

コードエディタの操作


コードエディタでのヘルプの表示
コードエディタでのヘルプの表示1010005

参照

コードエディタのほぼすべての部分で状況感知型のヘルプを使えます。状況はカーソルの現在位置に応じて決まります。

コードエディタウィンドウで状況感知型のヘルプを参照するには

次のどちらかの操作を行います。

ヘルプを参照したいプロパティ，イベント，メソッド，手続き，または型にカーソルを移動してから〔F1〕を押す

コードエディタを右クリックしてからスピードメニューで［この単語を検索(S)］を選択する

選択した特定の項目についてのヘルプがない場合，［トピックの検索］ダイアログボックスが表示されます。


参照1010006

コードエディタの操作


コードエディタウィンドウでのページの表示
コードエディタウィンドウでのページの表示1010007

参照

コードエディタのページを表示している場合，コードの特定の部分だけでなくページ内のすべてのデータをスクロールできます。

コードエディタにページを表示するには

次のいずれかの操作を行います。

コードエディタウィンドウがすでにアクティブな場合，表示するページに対応するタブをクリックする

［表示(V)｜ユニット(U)］を選択する

プロジェクトマネージャスピードメニューで［ユニットの表示(U)］を選択する

プロジェクトマネージャスピードバーで［ユニット表示］ボタンをクリックする


参照1010008

プロジェクトマネージャ

コードエディタの操作


コードエディタスピードメニュー
コードエディタスピードメニュー1010009

参照	スピードメニュー

コードエディタスピードメニューには，ソースコード内を移動したりソースコードを修正またはデバッグするためのコマンドがあります。コードエディタスピードメニューはコードエディタに固有であり，そのコマンドはコードエディタ専用です。

コードエディタスピードメニューのコマンドを次に示します。各コマンドについての詳細は次のリストのコマンドをクリックして参照してください。

このページを閉じる(C)

このファイルを開く(F)

別の編集ウィンドウを開く(N)

このシンボルを調べる(B)

この単語を検索(S)

インターフェースに追加(I)

ブレークポイントの設定(K)

カーソル位置まで実行(U)

評価/変更(E)

この単語を監視式に追加(A)

フォームとして表示(V)

書き込み禁止(O)

メッセージの表示(M)

プロパティ(R)

コードエディタスピードメニューを開くには

次のどちらかの操作を行います。

コードエディタウィンドウ内で右クリックする

コードエディタウィンドウがアクティブなときに〔Alt〕+〔F10〕を押す


参照1010010

コードエディタの操作


このページを閉じる(C) (コードエディタスピードメニュー)
このページを閉じる(C) (コードエディタスピードメニュー)1010011

コードエディタスピードメニュー

コードエディタスピードメニューで［このページを閉じる(C)］を選択すると，コードエディタウィンドウの現在のページを閉じます。

変更したコードを保存していない場合，ファイルを閉じようとすると新しいファイル名を入力するための［名前を付けて保存］ダイアログボックスが開きます。

まだ保存していないプロジェクトの最後のページを閉じようとすると，プロジェクト名を入力するための［名前を付けて保存］ダイアログボックスが開きます。


このファイルを開く(F) (コードエディタスピードメニュー)
このファイルを開く(F) (コードエディタスピードメニュー)1010012

コードエディタスピードメニュー

コードエディタスピードメニューで［このファイルを開く(F)］を選択すると，現在のカーソル位置にあるファイルが開きます。

ファイルの拡張子を明示的に指定しなかった場合，デフォルトの .PAS の拡張子のファイルが検索されます。ユニットファイルとインクルードファイルのディレクトリ設定については，［プロジェクト(P)｜オプション(O)］で表示されるダイアログボックスの［ディレクトリ/条件］ページに指定したディレクトリ設定が使われます。

ユニットファイルとインクルードファイルのディレクトリ設定を変更するには

1.	Delphi のメインメニューで［プロジェクト(P)｜オプション(O)］を選択します。

2.	［ディレクトリ/条件］ページをクリックします。

3.	ユニットファイルとインクルードファイルのディレクトリを設定します。

4.	［OK］を選択して新しい設定を有効にします。


別の編集ウィンドウを開く(N)（コードエディタスピードメニュー）
別の編集ウィンドウを開く(N)（コードエディタスピードメニュー）1010013

［表示(V)｜別の編集ウィンドウを開く(N)］を選択すると，オリジナルのコードエディタからコピーされたアクティブページを含む新しいコードエディタが開きます。

オリジナルかコピーのどちらかに加えた変更は，両方のファイルに反映されます。

ウィンドウを区別できるように，オリジナルのウィンドウでは 1，最初のコピーでは 2，2 番目のコピーでは 3 という具合にキャプションの後に番号が付きます。


このシンボルを調べる(B) (コードエディタスピードメニュー)
このシンボルを調べる(B) (コードエディタスピードメニュー)1010014

参照	コードエディタスピードメニュー

コードエディタスピードメニューで［このシンボルを調べる(B)］を選択すると，強調表示したシンボルの［シンボルを調べる］ウィンドウが開きます。

シンボルは，ソースコード内で定義したオブジェクト，ユニット，変数のシンボルのいずれかです (ソースコード内とは，現在のファイル内に限らず，同じプロジェクトの一部としてコンパイルとリンクをするいずれかのソースファイルも含みます)。

シンボルを参照するには，［プロジェクトオプション］ダイアログボックスの［コンパイラ］ページで［ローカル シンボル(L)］と［シンボル情報(Y)］のオプションを両方有効にしてコンパイルしなくてはなりません。


参照1010015

オブジェクトブラウザ


この単語を検索(S) (コードエディタスピードメニュー)
この単語を検索(S) (コードエディタスピードメニュー)1010016

コードエディタスピードメニュー

コードエディタスピードメニューで［この単語を検索(S)］を選択すると，コードエディタ内のカーソル位置にあるワードまたはトークンについてのヘルプウィンドウが表示されます。

ヘルプ項目がない場合，もっとも近い項目が強調表示された総合検索用の［キーワードで検索］ダイアログボックスが表示されます。


メッセージの表示(M)（コードエディタスピードメニュー）
メッセージの表示(M)（コードエディタスピードメニュー）1010017

コードエディタスピードメニュー

［メッセージの表示(M)］を選択すると，コードエディタの下部にあるメッセージウィンドウの表示が切り替わります。

メッセージウィンドウには，アプリケーションのコンパイル時にはエラーまたは警告のメッセージが表示され，検索の実行時には検索結果が表示されます。

メッセージウィンドウのスピードメニューには次のコマンドがあります。

［ソースの表示(V)］	コードエディタをスクロールして，メッセージウィンドウで選択されているエラーメッセージまたは検索結果の場所に移動します。

［ソースの編集(S)］	コードエディタをスクロールして，メッセージウィンドウで選択されているエラーメッセージまたは検索結果の場所に移動し，コードエディタをアクティブにします。

［コンパイラメッセージの消去］	メッセージウィンドウからコンパイラメッセージだけをクリアします。

［検索結果の消去(C)］	メッセージウィンドウから検索結果メッセージだけをクリアします。


ブレークポイントの設定(K) (コードエディタスピードメニュー)
ブレークポイントの設定(K) (コードエディタスピードメニュー)1010018

参照	コードエディタスピードメニュー

コードエディタスピードメニューで［ブレークポイントの設定(K)］を選択すると，現在のカーソル位置にあるブレークポイントの有効と無効が切り替わります。

ブレークポイントを設定していない場合，［ブレークポイントの設定(K)］コマンドを選択するとブレークポイントが設定され有効になります。ブレークポイントを設定してある場合，このコマンドを使うとブレークポイントが無効に切り替わります。

ブレークポイントプロパティを変更するには

ブレークポイントウィンドウ内で既存のブレークポイントを右クリックしてから［プロパティ(R)］を選択する


参照1010019

ブレークポイントの設定

ブレークポイントの使い方

Delphi のデバッガ


カーソル位置まで実行(U) (コードエディタスピードメニュー)
カーソル位置まで実行(U) (コードエディタスピードメニュー)1010020

参照	コードエディタスピードメニュー

［カーソル位置まで実行(U)］を選択すると，ロードプログラムがモジュールウィンドウ内のカーソル位置まで実行されます。

カーソル位置まで実行すると，プログラムは最大の速度で実行されてから一時停止し，カーソルのあるコード行に実行ポイントが移動します。

［カーソル位置まで実行(U)］を使うと，問題があると疑われる位置までプログラムを実行して一時停止できます。一時停止した後，［実行(R)｜ステップ実行(S)］または［実行(R)｜トレース実行(T)］を使ってコードの実行を 1 行ずつ制御できます。

［カーソル位置まで実行(U)］コマンドは次の方法でも実行できます。

［実行(R)｜カーソル位置まで実行(C)］を選択する


参照1010021

プログラム実行の制御

統合デバッガについて


評価/変更(E) (コードエディタスピードメニュー)
評価/変更(E) (コードエディタスピードメニュー)1010022

参照	コードエディタスピードメニュー

［評価/変更(E)］コマンドを使うと，既存の式の値の評価や変更ができる［評価/変更］ダイアログボックスが開きます。

［評価/変更(E)］コマンドは次の方法でも実行できます。

［実行(R)｜評価/変更(V)］を選択する


参照1010023

式の評価と変更

統合デバッガについて


この単語を監視式に追加(A) (コードエディタスピードメニュー)
この単語を監視式に追加(A) (コードエディタスピードメニュー)1010024

参照	コードエディタスピードメニュー

［この単語を監視式に追加(A)］コマンドを使うと，監視式の作成や変更ができる［監視式のプロパティ］ダイアログボックスが開きます。監視式を作成した後で現在の監視式のリストを表示したり管理するには，監視式一覧ウィンドウを使います。

［この単語を監視式に追加(A)］コマンドは次の方法でも実行できます。

コードエディタスピードメニューで［実行(R)｜監視式の追加(W)］を選択する

監視式一覧スピードメニューで［監視式の追加(A)］を選択する

既存の監視式を監視式一覧ウィンドウで右クリックしてから監視式一覧スピードメニューで［監視式の編集(E)］を選択する


参照1010025

監視式の設定

監視式

Delphi のデバッガ


書き込み禁止(O) (コードエディタスピードメニュー)
書き込み禁止(O) (コードエディタスピードメニュー)1010026

コードエディタスピードメニュー

コードエディタスピードメニューで［書き込み禁止(O)］を選択すると，現在開いているファイルが読み出し専用になります。読み出し専用のファイルは内容を変更できません。

ファイルを読み出し専用にすると，コードエディタスピードメニュー内の［書き込み禁止(O)］コマンドにチェックマークが付き，コードエディタのステータスラインに［書き込み禁止］と表示されます。


フォームとして表示(V) (コードエディタスピードメニュー)
フォームとして表示(V) (コードエディタスピードメニュー)1010027

このコマンドを使ってフォームをビジュアルオブジェクトとして表示します。

メモ:	このコマンドは，フォームをビジュアルオブジェクトとして表示しているときには［テキストとして表示(V)］に変わります。


コードエディタコントロールメニュー
コードエディタコントロールメニュー1010028

参照

コードエディタのコントロールメニューボックスはコードエディタウィンドウの左上隅にあります。コントロールメニューボックスを 1 回クリックするか〔Alt〕とスペースキーを同時に押すと，コントロールメニューが表示されます。コントロールメニューにあるコマンドを使うと，コードエディタウィンドウを操作できます。

コントロールメニューには次のコマンドがあります。

元のサイズに戻す(R)

移動(M)

サイズ変更(S)

最小化(N)

最大化(X)

閉じる(C)


参照1010029

コードエディタの操作


元のサイズに戻す(R) (コントロールメニュー)
元のサイズに戻す(R) (コントロールメニュー)1010030

コードエディタコントロールメニュー

［元のサイズに戻す(R)］を選択すると，コードエディタウィンドウの位置とサイズが，以前の位置とサイズに戻ります (以前が最大化または最小化であった場合を除きます)。

［元のサイズに戻す(R)］コマンドを使えるのは，コードエディタウィンドウを最大化または最小化している場合だけです。

ショートカット

コードエディタの右上隅で上下を向いた 2 つの三角形をクリックする


移動(M) (コントロールメニュー)
移動(M) (コントロールメニュー)1010031

コードエディタコントロールメニュー

［移動(M)］を選択すると，マウスでドラッグするのではなくキーボードを使ってコードエディタウィンドウを移動できます。

コードエディタウィンドウを移動するには

1.	コントロールメニューの［移動(M)］を選択します。

2.	キーボードの矢印キーを使ってウィンドウの位置を変更します。

3.	〔Enter〕を押します。

メモ:	コードエディタウィンドウを最大化している場合は［移動(M)］コマンドを使えません。

ショートカット

コードエディタのタイトルバーをドラッグする


サイズ変更(S) (コントロールメニュー)
サイズ変更(S) (コントロールメニュー)1010032

コードエディタコントロールメニュー

［サイズ変更(S)］を選択すると，境界をマウスでドラッグするのではなくキーボードを使ってコードエディタウィンドウのサイズを変更できます。

コードエディタウィンドウのサイズを変更するには

1.	コントロールメニューの［サイズ変更(S)］を選択します。

2.	キーボードの矢印キーを使ってウィンドウの境界を動かし，適当なサイズに変更します。

3.	〔Enter〕を押します。

メモ:	コードエディタウィンドウを最大化している場合は［サイズ変更(S)］コマンドを使えません。

ショートカット

コードエディタウィンドウの境界をドラッグする。垂直方向にサイズ変更するにはウィンドウの上下の境界をドラッグし，水平方向にサイズ変更するにはウィンドウの左右の境界をドラッグする。ウィンドウの 4 隅のいずれかを使うと水平方向と垂直方向のサイズを同時に変更できる


最小化(N) (コントロールメニュー)
最小化(N) (コントロールメニュー)1010033

コードエディタコントロールメニュー

［最小化(N)］を選択すると，コードエディタウィンドウがタイトルバーのサイズになります。

コードエディタをすでに最小化している場合は［最小化(N)］コマンドを使えません。

ショートカット

コードエディタの右上隅にある下向きの三角形をクリックする


最大化(X) (コントロールメニュー)
最大化(X) (コントロールメニュー)1010034

コードエディタコントロールメニュー

［最大化(X)］を選択すると，コードエディタウィンドウが拡大されて表示されます。

コードエディタウィンドウをすでに最大化している場合は［最大化(X)］コマンドを使えません。

ショートカット

コードエディタの右上隅にある上向きの三角形をクリックする


閉じる(C) (コントロールメニュー)
閉じる(C) (コントロールメニュー)1010035

コードエディタコントロールメニュー

［閉じる(C)］を選択すると，コードエディタのすべてのページとプロジェクトが閉じます。変更したコードを保存していない場合，新しいファイル名を入力するための［名前を付けて保存］ダイアログボックスが開きます。

［閉じる(C)］コマンドを使うと現在のプロジェクトも閉じます。プロジェクトを保存していない場合，プロジェクト名を入力する［名前を付けて保存］ダイアログボックスが開きます。

ショートカット

〔Alt〕+〔F4〕を押す

コードエディタのコントロールメニューボックスをダブルクリックする


選択領域を保存ダイアログボックス
選択領域を保存ダイアログボックス1010036

参照

［選択領域を保存］ダイアログボックスは，コードエディタウィンドウ内で選択したテキストブロックを書き出すファイルの名前と場所を指定するときに使います。

デフォルトのキー入力マッピングを使っている場合は，〔Ctrl〕+〔K〕+〔W〕でこのダイアログボックスが表示されます。


参照1010037

[ファイルから挿入] ダイアログボックス


ファイルから挿入ダイアログボックス
ファイルから挿入ダイアログボックス1010038

参照

［ファイルから挿入］ダイアログボックスは，コードエディタウィンドウの現在のカーソル位置に挿入する Object Pascal のソースコードブロックを含んだファイルの名前と場所を指定するときに使います。

デフォルトのキー入力マッピングを使っている場合は，〔Ctrl〕+〔K〕+〔R〕でこのダイアログボックスが表示されます。


参照1010039

[選択領域を保存] ダイアログボックス


イメージリストエディタ
イメージリストエディタ1010040

イメージリストエディタは，TImageList コンポーネントにビットマップとアイコンを追加するために設計時に使います。イメージリストエディタを表示するには，TImageList コンポーネントをダブルクリックするか，TImageList コンポーネントを右クリックしてから［イメージリストの設定(M)］を選択します。

［選択されたイメージ(S)］

［イメージ(I)］で選択したイメージに関する情報を表示します。このグループのコントロールは，利用可能なイメージがない場合は淡色表示になります。選択したイメージが，以前にエディタを使ったときに追加されている場合もコントロールは淡色表示になります。

［透過色(T)］

イメージを透過的に描画するためのマスクを作成するのに使う色を指定します。ビットマップでは最下行の左端のピクセルの色がデフォルトの透過の色になります。アイコンイメージでは［透過色(T)］は［clNone］に設定されます（アイコンはすでにマスクされています）。

［塗りつぶし色(F)］

イメージが TImageList コンポーネントより小さい場合に，イメージの切り取りや中央揃えのときにそのイメージの空の領域を塗りつぶす色を指定します。アイコンイメージでは［塗りつぶし色(F)］は［clNone］に設定されます。

［オプション］

新しく追加したビットマップイメージの幅または高さがイメージリストの幅または高さと合わない場合に，そのビットマップイメージを調整する方法を指定します（アイコンでは使えません）。

設定	説明

［そのまま(O)］	イメージの一部を左上隅から表示し，イメージリストの幅と高さを右下隅の方へ広げる（デフォルト）

［引き伸ばし(R)］	イメージ全体をイメージリストの幅と高さに収まるように広げる

［中央に置く(E)］	イメージリストの幅と高さの範囲内でイメージを中央に揃える。イメージの幅または高さがイメージリストの幅または高さより大きい場合，イメージを切り取ることができる

［イメージ(I)］

イメージリスト内のすべてのイメージのプレビューリスト表示と，イメージリストでのイメージの追加や削除のためのコントロールがあります。複数のイメージを簡単に確認できるように，各イメージは 24x24 の領域内で表示されます。各イメージの下には，イメージリスト内でのそのイメージの位置をゼロから始まる位置として示すキャプションがあります。このキャプションを編集してイメージリスト内でのイメージの位置を変更することも，イメージを新しい位置にドラッグすることもできます。

［追加(A)］

［イメージの追加］ダイアログボックスを表示します。このダイアログボックスでは，イメージリストに追加するビットマップまたはアイコンをいくつでも選択できます。選択するとイメージはプレビューリスト表示で強調表示され，それらのキャプションにはイメージリストでの連続した番号が割り当てられます。ビットマップが均一な単位でイメージリストの幅または高さより大きくなっている場合，イメージリストエディタでそのビットマップを複数のイメージに分割するかどうかを尋ねられます。これはツールバーのビットマップで役立ちます。通常，ツールバーのビットマップは連続した複数の小さなイメージで構成され，1 つの大きなビットマップとして格納されます。

［削除(D)］

選択したイメージをイメージリストから削除します。［削除(D)］のクリック後に残されたすべてのイメージについて，ゼロから始まる連続的なリストとなるように位置が設定し直されます。

［クリア(C)］

すべてのイメージをイメージリストから削除します。


Responding to tab-set changes
Responding to tab-set changes1012001

Example

When the user selects a tab in a tab-set control by clicking a tab or using the keyboard, the tab set generates an OnClick event. Any other controls that depend on the setting of the tab set need to have their values updated in response to those click events.

For example, with a tab set that contains tabs for each valid disk drive, a click on a different tab indicates a change of drive selection. Other controls, such as directory lists, need to respond to the change.

To respond to changes in a tab set, attach an event handler to the tab set's OnClick event.


Example1012002

The following code, attached to the OnClick event of a tab set named DriveTabSet, sets the Drive property in a directory-outline control to the first letter of the clicked tab:

procedure TFMForm.DriveTabSetClick(Sender: TObject);
begin
  with DriveTabSet do
    DirectoryOutline.Drive := Tabs[TabIndex][1];
end;


Responding to outline changes
Responding to outline changes1012003

Example

When the user selects an item in an outline by clicking it or using an arrow key, the outline generates a click. Any controls that depend on the currently selected item in the outline need to update themselves in response to those clicks.

For example, in a component such as the directory outline, a click probably indicates a change in the current directory. Related controls, such as file lists, need to respond to this change. However, it is possible that the click was on the directory already selected. Instead of handling the OnClick event, it is more useful to handle the OnChange event, which indicates that something in the directory outline has changed.

To respond to changes in an outline, attach a handler to the outline's OnChange event.


Example1012004

The following code updates both a file list box and a status-bar panel to reflect the current directory in a directory outline component every time the directory outline changes:

procedure TFMForm.DirectoryOutlineChange(Sender: TObject);
begin
  FileList.Directory := DirectoryOutline.Directory;
  DirectoryPanel.Caption := DirectoryOutline.Directory;
end;


Responding to list box changes
Responding to list box changes1012005

Example

When the user clicks an item in a list box or uses an arrow key to move to an item, that item becomes the selected item, and the list box generates an OnChange event. The application can handle the change and update any dependent controls.

To respond to changes in a list box, attach an event handler to the list box's OnChange event.

For example, a file list box can have an associated panel that displays information about the selected file or files.


Example1012006

The following event handler for a file list box's OnChange event updates a status-bar panel with the name and size of the file currently selected in a file list box.

Note:	GetFileSize is a function in the FMXUtils unit installed with the file manager sample application.

procedure TFMForm.FileListChange(Sender: TObject);
var
  TheFileName: string;
begin
  with FileList do
  begin
    if ItemIndex >= 0 then	{ is there a selected item? }
    begin
      TheFileName := FileName;	{ get the file name }
      FilePanel.Caption := TheFileName + ',

        { set panel caption to the name }
        + IntToStr(GetFileSize(TheFileName)) + ' bytes';

        { and size }
    end

    else FilePanel.Caption := '';	{ blank panel if none selected }
  end;
end;


Creating an owner-draw control
Creating an owner-draw control1012007

Windows list-box and combo-box controls have a style available called "owner draw," which means that instead of using Windows' standard method of drawing text for each item in the control, the control's owner (generally the form) draws each item at run-time. The most common application for owner-draw controls is to provide graphics instead of, or in addition to, text for items.

The following Delphi components support the owner draw style:

List-box

Combo-box

Status Panel	Header Section

Owner-draw list box and combo box controls contain lists of items. Those lists are lists of strings, which Windows displays as text. Delphi enables you to associate an object with each item in a list, and gives you the chance to use that object when drawing items.

To create an owner-draw control in Delphi follow the following three steps:

1.	Set the owner-draw style

2.	If the control is a list box or combo box, add graphical objects to a string list

3.	Draw owner-draw items


Setting the owner-draw style
Setting the owner-draw style1012008

Each control that has an owner-draw variant has a property called Style. Style determines whether the control uses the default drawing (called the "standard" style) or owner drawing.

For list boxes and combo boxes, there is also a choice of owner-draw styles, called fixed and variable, as the following table describes. Owner-draw status panels, header sections, and grids are always fixed.

Owner-draw style	Meaning	Examples
Fixed	Each item is the same height, If the control is a list box or combo box,  that height is determined by the ItemHeight property.	lbOwnerDrawFixed, csOwnerDrawFixed; psOwnerDraw; hsOwnerDraw
Variable	Each item might have a different height, deter-mined by the data at run time.	lbOwnerDrawVariable, csOwnerDrawVariable
To set the owner-draw style,

Set Style property for the owner-draw component.  With Owner draw grids, use the DefaultDrawing property instead.


Adding graphical objects to a string list
Adding graphical objects to a string list1012009

See also

Every Delphi string list can hold objects in addition to strings. That is, in addition to its indexed Strings property, which contains strings, a string list also has an Objects property.

Once you have graphical images in an application, you can associate them with the Objects property in a string list. You can either add the objects at the same time as the strings, or associate objects with already-added strings. If you have all the needed data available, you should generally add strings and objects together.

To add a graphical object to an existing string in a string list,

Assign the object to the Objects property at the same index.


See also1012010

Adding objects to a string list


Adding images to an application
Adding images to an application1012011

An image control is a non-visual component that contains a graphical image, such as a bitmap. You use image controls to display graphical images on a form, but you can also use them to hold hidden images that you will use in your application. For example, you can store bitmaps for owner-draw controls in hidden image controls.

To add an image to an application,

1.	Add an image control to the main form.

2.	Set its Visible property to False.

3.	Set the Picture property to display the bitmapped image.

Note:	The image will be visible on the form but when you run the application they will be invisible.


Drawing owner-draw items
Drawing owner-draw items1012012

When you set a control's style to owner draw, Windows no longer draws the control on the screen. Instead, it generates events for each visible item in the control. Your application handles the events to draw the items.

To draw the items in an owner-draw control,

1.	Size the item.

If the owner-draw items are all the same size (for example, with a list box style of lsOwnerDrawFixed), you do not need to do this step.

2.	Draw the item.


Sizing owner-draw items
Sizing owner-draw items1012013

Before giving your application the chance to draw each item in a variable owner-draw control, Windows generates a measure-item event. The measure-item event tells the application where the item will appear on the control.

Delphi determines what size the item will probably be (generally just large enough to display the item's text in the current font). Your application can handle the event and change the rectangle Delphi chose. For example, if you plan to substitute a bitmap for the item's text, you would change the rectangle to be the size of the bitmap. If you want the bitmap and text, you adjust the rectangle to be big enough for both.

To change the size of an owner-draw item, attach an event handler to the OnMeasureItemevent in the owner-draw control.

The sizing event has two important parameters: The index number of the item and the size of that item. That size is variable: the application can make it either smaller or larger. The positions of subsequent items depends on the size of preceding items.

For example, in a variable owner-draw list box, if the application sets the height of the first item to five pixels, the second item starts at the sixth pixel down from the top, If the application then sets the height of the second item to ten pixels, the third item starts at the sixteenth pixel from the top, and so on.


Drawing each owner-draw item
Drawing each owner-draw item1012014

When an application needs to draw or redraw an owner-draw control, Windows generates draw-item events for each visible item in the control.

To draw each item in an owner-draw control, attach an event handler to the draw-item event for that control. The events for owner drawing are:

OnDrawCell

OnDrawColumnCell

OnDrawItem

OnDrawPanel	OnDrawSection

The draw-item event contains

parameters indicating the index of the item to draw

the rectangle in which to draw

information about the state of the item (such as whether the item has focus).

The application handles each event by rendering the appropriate item in the given rectangle.

Note:	Most draw-item events do not pass a canvas object as a parameter; you normally use the canvas of the control being drawn.


Manipulating files
Manipulating files1012015

There are several common file operations built into Object Pascal's run-time library. The procedures and functions for working with files operate at a high level: You specify the name of the file you want to work on, and the routine makes the necessary calls to the operating system for you.

Previous versions of the Pascal language performed similar operations on files themselves, rather than on file names. That is, you had to locate a file and assign it to a file variable before you could, for example, rename the file. By operating at the higher level, Object Pascal reduces your coding burden and streamlines your applications. The lower-level functions are still available, but you should not need them as often.

Choose a topic for more information.

Deleting a file

Renaming a file

Changing a file's attributes


Deleting a file
Deleting a file1012016

Example

Deleting a file erases the file from the disk and removes the entry from the disk's directory. There is no corresponding operation to restore a deleted file, so applications should generally allow users to confirm deletions of files.

To delete a file, pass the name of the file to the DeleteFile function. DeleteFile returns True if it deleted the file and False if it did not (for example, if the file did not exist or if it was read-only).


Example1012017

The following code handles a click on a File|Delete menu item by deleting the selected file in a file list box, then updating the list so it reflects the deletion.

procedure TFMForm.Delete1Click(Sender: TObject);
begin
  with FileList do
    if DeleteFile(FileName) then Update;
end;


Changing file attributes
Changing file attributes1012018

See also	Example

Every file has various attributes stored by the operating system as bitmapped flags. File attributes include such items as whether a file is read-only or a hidden file.

Changing a file's attributes requires three steps:

1.	Reading file attributes.

2.	Changing individual file attributes.

3.	Setting file attributes.

You can use the reading and setting operations independently, if you only want to determine a file's attributes, or if you want to set an attribute regardless of previous settings. To change attributes based on their previous settings, however, you need to read the existing attributes, modify them, and write the modified attributes.

Reading file attributes

Operating systems store file attributes in various ways, generally as bitmapped flags.

To read a file's attributes, pass the file name to the FileGetAttrfunction. The return value is a group of bitmapped file attributes, of type Word.

Changing individual file attributes

Because Delphi represents file attributes in a set, you can use normal logical operators to manipulate the individual attributes. Each attribute has a mnemonic name defined in the SysUtils unit.

For example, to set a file's read-only attribute, you would do the following:

Attributes := Attributes or faReadOnly;

You can also set or clear several attributes at once. For example, the clear both the system-file and hidden attributes:

Attributes := Attributes and not (faSysFile or faHidden);

Setting file attributes

Delphi enables you to set the attributes for any file at any time.

To set a file's attributes, pass the name of the file and the attributes you want to the FileSetAttr function.


See also1012019

FindFirst function


Example1012020

The following code reads a file's attributes into a set variable, sets the check boxes in a file-attribute dialog box to represent the current attributes, then executes the dialog box. If the user changes and accepts any dialog box settings, the code sets the file attributes to match the changed settings:

procedure TFMForm.Properties1Click(Sender: TObject);
var
  Attributes, NewAttributes: Word;
begin
  with FileAttrForm do
  begin
    FileDirName.Caption := FileList.Items[FileList.ItemIndex];
    { set box caption }
    PathName.Caption := FileList.Directory;
    { show directory name }
    ChangeDate.Caption :=
      DateTimeToStr(FileDateTime(FileList.FileName));
    Attributes := FileGetAttr(FileDirName.Caption);
    { read file attributes }
    ReadOnly.Checked := (Attributes and faReadOnly) = faReadOnly;
    Archive.Checked := (Attributes and faArchive) = faArchive;
    System.Checked := (Attributes and faSysFile) = faSysFile;
    Hidden.Checked := (Attributes and faHidden) = faHidden;
    if ShowModal <> id_Cancel then	{ execute dialog box }
    begin
      NewAttributes := Attributes;
      { start with original attributes }
      if ReadOnly.Checked then
        NewAttributes := NewAttributes or faReadOnly
      else
        NewAttributes := NewAttributes and not faReadOnly;
      if Archive.Checked then
        NewAttributes := NewAttributes or faArchive
      else
        NewAttributes := NewAttributes and not faArchive;
      if System.Checked then
        NewAttributes := NewAttributes or faSysFile
      else
        NewAttributes := NewAttributes and not faSysFile;
      if Hidden.Checked then
        NewAttributes := NewAttributes or faHidden
      else
        NewAttributes := NewAttributes and not faHidden;
      if NewAttributes <> Attributes then { if anything changed... }
        FileSetAttr(FileDirName.Caption, NewAttributes);
         { ...write the new values }
    end;
  end;
end;


Reusing forms as DLLs
Reusing forms as DLLs1013001

See also

When you create a form that you want to use in multiple applications, especially when the applications are not Delphi applications, you can build the form into a dynamic-link library (DLL). A DLL is a compiled executable file, so applications written with tools other than Delphi can call them. For example, you can call a DLL from applications created with C++, Paradox, or dBASE.

DLLs are standalone files that contain the overhead of the component library (about 100K). You can minimize this overhead by compiling several forms into a single DLL. For example, suppose you have a suite of applications that all use the same dialog boxes for checking passwords, displaying shared data, or updating status information. You can compile all of these dialog boxes into a single DLL, allowing them to share the component-library overhead.

Building a form into a DLL takes three steps:

1.	Declaring interface routines

2.	Modifying Project file

3.	Accessing routines stored in DLLs


See also1013002

Writing DLLs


Declaring an interface routine
Declaring interface routines1013003

See also	Example

When you are compiling an application into a DLL, interface routines enable you to access the routine in the DLL from an outside application.

Adding an interface-routine declaration involves declaring a procedure or function in the interface section of the unit to be compiled into the DLL, and following that declaration with the export directive.

When writing interface routines that will be called from languages other than Object Pascal, you must declare parameters and return values using types that are available in the calling language. For example, you should pass strings as null-terminated arrays of characters (the Object Pascal type PChar) rather than Object Pascal's native string type.

After declaring an interface routine, you can define the routine in the implementation section of the unit.


See also1013004

Accessing routines stored in DLLs

Functions

Interfaces

Procedures

Writing DLLs


Example1013005

The following example declares the function GetPassword as a interface routine. The exports section includes the GetPassword routine name to ensure that the function is successfully exported.

unit PassForm;

interface

uses

  SysUtils, Windows, Messages, Classes, Graphics,

  Forms, Controls, Forms, Dialogs, StdCtrls, Buttons;

type

  TPasswordForm = class(TForm)

  ...	{ various declarations go here }

  end;

var

  PasswordForm: TPasswordForm;

function GetPassword(APassword: PChar; hAppHandle: THandle): WordBool;

exports GetPassword;

implementation

function GetPassword(APassword: PChar; hAppHandle: THandle): WordBool;

begin

  Application.Handle := hAppHandle; { Associate the DLL�s Application handle with the
               loading Application�s handle. }

  PasswordForm := TPasswordForm.Create(Application);

  try

    if PasswordForm.ShowModal = mrOK then

    begin

      {Code to validate entered password values here}

      Result := True;

    end;

  finally

    PasswordForm.Free;

  end;

end;

end.


Compiling a project into a DLL
Compiling a project into a DLL1013006

See also	Example

When you are compiling a project into a DLL, you need to make the following edits in the project file:

1.	Change the reserved word program in the first line of the file to library.

2.	Remove the Forms unit from the project's uses clause.

3.	Remove all lines of code between the begin and end at the bottom of the file.

4.	Below the uses clause, and before the begin..end block, add the reserved word exports, followed by the names of the interface routines and a semicolon.

Delphi will not create the list of interface routines to be exported.

After these modifications, when you compile the project, it produces a DLL instead of an application. Applications can now call the DLL to open the wrapped dialog box.


See also1013007

Declaring interface routines

Writing DLLs


Example1013008

The following example shows a typical project file before and after modification:

program Password;

uses Forms,

     PassForm in 'PASSFORM.PAS' {PasswordForm};

{$R *.RES}

begin

  Application.CreateForm(TPasswordForm, PasswordForm);

  Application.Run;

end.

After modifications:

library Password;	{ 1. reserved word changed }

uses	{ 2. removed Forms, }

     PassForm in 'PASSFORM.PAS' {PasswordForm};

exports

  GetPassword;	{ 4. add exports clause }

{$R *.RES}

begin	{ 3. remove code from main block }

end.


別名でのフォームの保存
別名でのフォームの保存1014001

参照

［ファイル(F)｜名前を付けて保存(A)］を選択すると，フォームを別名で保存したり別の場所に保存できます。ただし，［名前を付けて保存］ダイアログボックスでは .DFM ファイルはユニットファイルと別々に表示されません。設計時にフォームを変更し，基になるソースコードを変更しなくても，ファイルを保存するときに表示されるのは .PAS ファイルだけです。この 2 つのファイルは不可分であり，一方を保存するともう一方も保存されます。

フォームを別名で保存すれば，そのフォームを変更しても，元の名前のフォームを使っているかもしれないほかのプロジェクトには影響を及ぼさずに済みます。

フォームを別名で保存するには

1.	保存するフォームを選択します。

2.	［ファイル(F)｜名前を付けて保存(A)］を選択します。

3.	［名前を付けて保存］ダイアログボックスでファイルの名前とディレクトリを指定します。

4.	［OK］を選択します。


参照1014002

オブジェクトリポジトリへのフォームの追加

ファイルの保存

プロジェクトと個々のプロジェクトファイルの保存


パスワード文字のマスク
パスワード文字のマスク1014003

参照	例

編集フィールドまたはメモフィールドにユーザーが入力する文字をマスクできます。Edit，DBEdit，MaskEdit の各コンポーネントの PasswordChar プロパティを使うと，ユーザーが入力する文字をアスタリスク (*) やシャープ記号 (#) などの特殊文字として表示できます。

この例についてはパスワードダイアログフォームテンプレートを開いて参照してください。

メモ:	パスワードダイアログフォームテンプレート の Edit コンポーネントの PasswordChar プロパティはアスタリスク (*) に設定してあります。実行時にユーザーがこのダイアログボックスにテキストを入力すると，アスタリスクだけが表示され，ユーザーのパスワードは画面に表示されません (任意の 1 文字を PasswordChar プロパティの値に設定できます)。


例1014004

次の例は，Button1 がクリックされたときにパスワードダイアログフォームテンプレートを表示ます。

1.	新しい空白プロジェクトを開き，そのプロジェクトにパスワードダイアログフォームテンプレートを追加します。

2.	Form1 にボタンを追加し，次の OnClick イベントハンドラを記述します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  PasswordDlg.ShowModal;

end;

3.	Unit1 の uses 節に Password を追加し，アプリケーションを実行します。

4.	Button1 を選択します。

［パスワードダイアログ］が表示されます。

5.	編集ボックスに何かテキストを入力します。

アスタリスクだけが表示されます。


参照1014005

TEdit コンポーネント

TDBEdit コンポーネント

TMaskEdit コンポーネント

プロジェクトへのフォームの追加


オブジェクトリポジトリへのフォームの追加
オブジェクトリポジトリへのフォームの追加1014006

一度作成したカスタムダイアログボックスをほかのプロジェクトでも再利用したい場合があります。オブジェクトリポジトリにフォームを追加すれば簡単に再利用できます。

オブジェクトとしてのフォームの保存はフォームのコピーの別名保存と同じです。ただし，フォームをオブジェクトとして保存すると，そのフォームは オブジェクトリポジトリのリストに表示されます。このリストに表示するオブジェクトのビットマップと説明文を指定します。

カレントフォームをオブジェクトリポジトリに追加するには

1.	フォームを右クリックしてフォームスピードメニューを表示します。

2.	フォームスピードメニューで［リポジトリに追加(R)］コマンドを選択します。

［リポジトリに追加］ダイアログボックスが表示されます。

3.	［タイトル(T)］編集ボックスにオブジェクトの名前を入力します。

4.	［コメント(D)］編集ボックスにこのオブジェクトの簡単な説明文を入力します。

5.	［新規作成］ダイアログボックスに表示されるときのページを選択します。

6.	フォームの作者を指定できます。作者はオブジェクトリポジトリの詳細ビューでのみ表示されます。

7.	オブジェクトのアイコンを指定するために［参照(B)］ボタンを選択します。

［アイコンの選択］ダイアログボックスが表示されます。

8.	使いたいビットマップがあれば探して選択し，次に［OK］を選択して［アイコンの選択］ダイアログボックスを閉じます。

9.	［OK］を選択すると，指定した内容が確定されて［リポジトリに追加］ダイアログボックスが閉じます。

この後で［ファイル(F)｜フォームの新規作成(F)］を選択すると，追加したテンプレート，そのテンプレートを表すビットマップ，入力した説明文がテンプレートリストに表示されます。


リポジトリに追加ダイアログボックス
リポジトリに追加 (フォームスピードメニュー)1014007

［リポジトリに追加］ダイアログボックスを使って新しいフォームをオブジェクトリポジトリに追加します。

［リポジトリに追加］ダイアログボックス

［フォーム(F)］

現在のオブジェクト内のフォームの名前を表示します。

［タイトル(T)］

このボックスを使ってリポジトリに追加するフォームの名前を指定します。

［コメント(D)］

このボックスを使ってフォームの説明を入力します。この説明は，［新規作成］ダイアログボックスでスピードメニューから［詳細表示(D)］オプションを選択したときに表示されます。

［ページ(P)］

オブジェクトリポジトリ内の現在のページのリストを表示します。このオプションを使って，フォームを追加したいリポジトリページを選択します。

［作者(A)］

このボックスを使って追加したい作者名を入力します。

［参照(B)］ボタン

［参照(B)］ボタンを使って，リポジトリに追加したいフォームのアイコンを変更します。アイコンは，［新規作成］ダイアログボックスと［オブジェクトリポジトリ］ダイアログボックスに表示されるビットマップを表します。このビットマップを変更するには，［参照(B)］ボタンをクリックして［アイコンの選択］ダイアログボックスを開きます。

どんなサイズのビットマップでも使用できますが，60 x 40 ピクセルに切り取られます。


Glossary
Glossary1015001

A1015002

abstract

accelerator key

actual parameter

actual variable

alias

ancestor

application

array

ASCII

B1015003

base type

batch operation

BDE

BDE Adminstrator

BDE Configuration Utility

BLOB

block

Boolean

Borland Database Engine

breakpoints

byte

C1015004

callback routines

call stack

canvas

case variant

char

child

class

class method

client

client area

column

compile

compiler directive

compile time

compile-time error

complete evaluation

component

conditional symbol

const parameter

constant

constant address expression

container application

container component

control

D1015005

data

data access component

data-aware

data control component

data type

database

database server

dataset

DDE client

DDE conversation

DDE server

default ancestor

default event

default new form

default new project

derive

descend

descendant

design time

design-time package

detail table

dispatch

drag

dynamic

dynamic data exchange (DDE)

dynamic-link library (DLL)

E1015006

embedding

encapsulate

end user

enumerated data type

exception

exception handler

execution point

expressions

event

event handler

F1015007

feature

field

file buffer

file type

filter

filter program

focus

form

formal parameter

function

function header

G1015008

global heap

global variable

glyph

grandchild

grandparent

grid

H1015009

handling exceptions

header

heap

heap suballocator

help context

Hint

host type

IJK1015010

IDAPI

identifier

implementation

include file

index

index type

inheritance

instance

integer

integrated debugger

interface

key

L1015011

label

language driver

late binding

linking

literal value

local heap

local symbol information

local variable

lock

logic error

Longint

lookup table

loop

M1015012

main form

master table

method

method identifier

method pointer

MDI application

modal

modeless

module

N1015013

nil

nonvisual component

nonwindowed control

O1015014

object file

object instance variable

object type

OLE

OLE container

OLE object

OLE server

ordinal

override

owner

P1015015

package

parameter

parent

pixel

pointer

power set

primary index

private

private part

procedure

procedure header

program

project

project directory

project file

property

protected

protected block

public

published

Q1015016

qualified identifier

qualified method identifier

qualifier

query

R1015017

raise

real

record

record type

recursion

relational database

report

root class

routine

row

run time

run-time error

run-time library

run-time only

run-time package

S1015018

scalar type

scope

separator

separator bar

set

short-circuit evaluation

Shortint

sizing handles

source code

splash screen

SQL

SQL table

stack

statement

static

step over

string

string list

subrange

switch directive

symbol

T1015019

table

tag field

template

trace into

typecasting

type

type definition

typed constant

U1015020

unit

untyped file

untyped pointer

unqualified identifier

use count

user-defined

V1015021

value parameter

variable parameter

variable

virtual

visual component

W1015022

watches

window handle

windowed control

word

wrapper

XYZ1015023

z-order


abstract1015024

A method that is declared but not implemented. Descendant types must override the abstract method.


accelerator key1015025

Accelerator keys enable the user to access a menu command or component from the keyboard, by pressing Alt+ the appropriate letter, indicated in your code by the preceding ampersand. The letter after the ampersand appears underlined in the menu or component caption.


actual parameter1015026

A variable, expression, or constant that is substituted for a formal parameter in a procedure or function call.


actual variable1015027

A variable that a program can use at run time, as distinguished from the definition of that variable within the program. A location in memory used for storage purposes, as distinguished from an identifier.


alias1015028

A name that specifies the location of database tables. If the database is on a server, an alias also specifies connection parameters for the server.


ancestor1015029

An object from which another object is derived. An ancestor class can be a parent or a grandparent. See default ancestor.


application1015030

An application is the executable file and all related files that a program needs to function which serve a common purpose or purposes, as distinguished from the design and source code of the project. Often used synonymously with 'program'. Compare with program and project.


array1015031

A group of data elements identical in type that are arranged in a single data structure and are randomly accessible through an index.


ASCII1015032

An acronym for "American Standard Code for Information Interchange" and used to describe the byte values assigned to specific characters. Examples: The capital letter A has an ASCII value of 65. The ASCII code for a space is 32.

In Pascal, you can reference a character by its ASCII code prefixed with a number sign (#). Example: To put the symbol for American cents into a character C, for example, you could code "c := #155;".


base type1015033

The type referred to in a pointer declaration, an array declaration, or the enumeration type used in a set declaration. A type declaration builds a new type by combining or referencing one or more other base types, which could themselves be arbitrarily complex.


batch operation1015034

Operations that you perform with the TBatchMove component on groups of records, or on datasets, to add, delete, or copy groups of records in a single operation.


BDE1015035

Borland Database Engine; also referred to in some documentation as IDAPI. Delphi uses this database engine to access and deliver data. BDE maintains information about your PC's environment in the BDE configuration file (usually called IDAPI.CFG). Use the BDE Configuration Utility to change the settings in this configuration file.


BDE Administrator1015036

A program that enables you to change the settings in the BDE configuration file, usually called IDAPI.CFG. The executable file is named BDEADMIN.EXE. Formerly called the BDE Configuration Utility.


BDE Configuration Utility1015037

See BDE Administrator.


BLOB1015038

Binary large object. Many database tables use specific field types to contain BLOB data. Delphi lets you access BLOB data that exists as plain text with the TDBMemo component, and BLOB data that exists as a graphic with the TDBImage component.


block1015039

The associated declaration and statement parts of a program or subprogram. Examples: In the var block of the routine declare an integer variable. Follow the then of your if..then statement with a begin to start a block of code that will be executed only if the condition is met.


Boolean1015040

A data type that can have a value of either True or False. Data size = byte.


Borland Database Engine1015041

See BDE.


breakpoints1015042

A location you mark in your program where you want the program to pause during a debugging session. Once the program's execution has been paused, you can examine the state of your program at that point in its execution. The state of your program includes the values of variables and data structure elements and the routines on the call stack.


byte1015043

A data type capable of holding a value from 0 to 255. A sequence of 8 bits.


callback routines1015044

Routines in your application that are called by Windows and not by your application. For example, EnumFonts is a Windows routine that will call the given callback function for every font installed in the system.


call stack1015045

The list of calls that were made to reach the present location, and which consequently show the path by which the program must return. Available during debugging.


canvas1015046

The graphical drawing surface of an object. The canvas has a brush, a pen, a font, and an array of pixels. The canvas encapsulates the Windows device context.


case variant1015047

1.	The element of a case statement that is examined to determine what code will be executed. In a case statement beginning "Case I of", I is the case variant.

2.	In record type definitions, case variants allow instances of that record to treat the same area of memory as different fields.


char1015048

A Pascal type that represents a single character.


child1015049

1.	A child class is any class that is descended from another. For example, in "type B = class(A)", B is a child of A. Compare with grandchild.

2.	The child of a window appears inside that window and cannot draw outside of its bounds. This is called a child or child window.


class1015050

A list of features representing data and associated code assembled into single entity. A class includes not only features listed in its definition but also features inherited from ancestors. The term "class" is interchangeable with the term "object type."


class method1015051

Class methods provide behavior for a class that is global in nature, or otherwise does not require instance data. A class method is called by using the class name followed by the method (TClass.SomeMethod) and can be called with an instance or without. As such, a class method cannot rely on any properties, fields or instance methods in its executions.


client1015052

Generically, any thing that requests the services of something else. In Object Pascal, a client is any code that uses one or more features of an object or unit. In Windows, a client is code that makes use of the Windows API.

In database systems, a workstation connected to an intelligent "back-end" server from which it can request data. The client workstation can process the data locally and write it back to the server.


client area1015053

In Windows, the area of a control which a program (that is, a client of Windows' services) is allowed to draw on. On a window, for example, that would usually exclude the frame and title bar.


column1015054

The vertical component of a table, sometimes called a field. A column contains one value for each row in a table. See also row.


compile1015055

The act of translating a block of source code into machine instructions. (As opposed to "interpret" which is the line-by-line translation of source code to machine instructions.)

Also see linking.


compiler directive1015056

An instruction to the compiler that is embedded within the program; for example, {$R+} turns on range checking.


compile time1015057

The period of time when the compiler is actively compiling source code.


compile-time error1015058

An error detected by the compiler during compilation, such as a syntax error or unknown identifier.


complete evaluation1015059

Every operand in a Boolean expression built from the and and or operators evaluates, even if the expression result can be determined before the entire expression is evaluated. This is useful when operands are routines that can alter the meaning of a program. Opposite of short-circuit Boolean evaluation.


component1015060

1.	The elements of a Delphi application, iconized on the Component palette. Components, including forms, are objects you can manipulate. Forms are components that can contain other components (forms are not iconized on the Component palette).

2.	In Delphi, any class descended from TComponent is, itself, a component. In the broader sense, a component is any class that can be interacted with directly through the Delphi Form Designer. A component should be self-contained and provide access to its features through properties.

3.	In traditional Pascal, the word "component" is also sometimes used synonymously with feature, as in "The record consists of several components: three string fields and two byte fields."


conditional symbol1015061

Used with conditional compiler directives to specify a condition that is either true or false. You define (set to true) or undefine (set to false) conditional symbols with the $DEFINE and $UNDEF directives.


constant1015062

An identifier with a fixed value in a program. At compile time, all instances of a constant in source code are replaced by the fixed value. Contrast with typed constant.


constant address expression1015063

An expression that takes the address, the offset, or the segment of a global variable, a typed constant, a procedure, or a function.

Constant address expressions cannot reference local variables (stack-based) or dynamic (heap-based) variables, because their addresses cannot be computed at compile time.


const parameter1015064

A const (constant) parameter is one that is passed by reference but that cannot be changed by the procedure. Const is more efficient in performance and memory usage a than a value parameter. See value parameter and variable parameter.


container application1015065

An application that contains an embedded OLE object. (See OLE.)


container component1015066

Any of several component classes that have the inherent ability to contain other components. Examples include TForm, TPanel, TNotebook, and TGroupbox. A container component is the parent of the components it contains.


control1015067

A visual component. Specifically, any descendant of TControl.


data1015068

1.	Information stored in a database. Data may be a single item in a field, a record that consists of a series of fields, or a set of records. Delphi applications can retrieve, add, modify, or delete data in a database.

2.	Generally, any information that has intrinsic value regardless of the means used to access it.


data access component1015069

A Delphi component that enables you to connect to a database and access its data. Data access components are visible on a form only at design time, not at run time.


data-aware1015070

Able to display and update data stored in an underlying table. All Delphi data control components are data-aware.


data control component1015071

A Delphi component that enables you to create the interface of a database application. Many data controls are data-aware versions of component classes available on the Standard page of the Component palette.


data type1015072

A fundamental unit of data definition that defines what kind of data can be stored in memory or in data tables, and what operations can be performed on that data.


database1015073

A collection of data in tables.


database server1015074

A system that manages relational databases. For example, SQL Server is a type of database server.


dataset1015075

A collection of data determined by a TTable, TQuery, or TStoredProc component. A dataset defined by TTable includes every row in a table, and a dataset defined by a TQuery contains a selection of rows and columns from a table.


DDE client1015076

In a DDE conversation, the client is the application that requests data. The DDE client is often called the destination.


DDE conversation1015077

A link between a DDE client application and a DDE server application which provides a means for both applications to continuously and automatically send data back and forth.


DDE server1015078

In a DDE conversation, the server is the application that updates the DDE client. The DDE server is often called the source.


default ancestor1015079

The ancestor of any class that does not specify an ancestor: TObject.


default event1015080

For a given component, the event whose event handler is automatically generated or displayed in the unit source code when you double-click the component at design time. For example, the OnClick event is the default event for a Button component.


default new form1015081

The Form Template that is used to create a new form in the IDE at design time when you choose File | New Form. In a new installation, the Blank Form template is used. You can change the specified Form Template in the Environment Options dialog box (Options | Environment | Gallery).


default new project1015082

The Project Template that is used to open a new Delphi project in the IDE at design time when you choose File | New Project. In a new installation, the Blank Project template is used. You can change the specified Project Template in the Environment Options dialog box (Options | Environment | Gallery).


derive1015083

To create a new class based on an existing class. The new class inherits all of the features of the existing class, which is called its parent or, more generically, an ancestor.


descend 1015084

To acquire, in the process of being created, all the characteristics of another class. A class that descends from another is a descendant of the parent class. The process of creating a descendant class is deriving.

See also ancestor, derive, descendant, inheritance, and parent.


descendant1015085

An object derived from another object. A descendant is type compatible with all of its ancestors.


design time1015086

Period when you can use Delphi to design your application, using the form, the Object Inspector, Component palette, Code Editor, and so forth; as opposed to run time, when the application you design is actually running.


design time package1015087

A special dynamic-link library used by the Delphi IDE to install components and to create special property editors for custom components.


detail table1015088

In multi-table relationships, the table whose records are subordinate to those of the master table. In a data model, the detail table is the one being pointed to by another table. For example, in the following data model, all of the tables except CUSTOMER.DB are detail tables.


dispatch1015089

The means of resolving calls to object methods. Dispatching can be either static, virtual, or dynamic.

Do not confuse with TObject.Dispatch which dispatches message procedure calls, not virtuals.


drag1015090

To move an object from one location to another by using your mouse.

To drag an object, click it and continue to hold down the left mouse button while you move the mouse pointer to a new location on your screen. When you are satisfied with the new location, release the mouse button.


dynamic1015091

A form of virtual method which is more space efficient (but less speed efficient) than simple virtual.


dynamic data exchange (DDE)1015092

The process of sending data to and receiving data from other applications through a predefined message protocol. You can use this to exchange data with other applications, or you can control other applications through the use of commands and macros.


dynamic-link library (DLL)1015093

An executable module (extension .DLL) that contains code or resources that can be accessed by other DLLs or applications. In the Windows environment, DLLs permit multiple applications to share code and resources.


embedding1015094

The act of placing one thing within another. In Windows, specifically the capability of one application to provide some or all of the services of another application integrated with its own services. For example, a word processor might allow a spreadsheet to be embedded into a document, allowing the user to write text around the spreadsheet and perhaps even change the spreadsheet while still working in the word processor. See OLE Container.


encapsulate1015095

To provide access to one or more features through an interface that protects clients from relying upon or having to know the inner details of the implementation.


enumerated data type1015096

A user-defined ordinal type that consists of an ordered list of identifiers.


end user1015097

A member of an application's intended audience and, by extension, everyone in that audience. Synonymous with user, but emphasizes the fact that the programmer is not the user.

In Delphi documentation end user refers to a user of an application you develop using Delphi unless otherwise noted.


exception1015098

An event or condition that, if it occurs, breaks the normal flow of execution. Also, an exception is an object that contains information about what error occurred and where it happened.


exception handler1015099

Code designed to resolve the situation in the run-time environment that raised the exception and/or to restore the environment to a stable state afterwards.


execution point1015100

The execution point indicates the next line in your program that will be executed when you run your program through the integrated debugger. The execution point is indicated by highlighted line of code in the Code Editor.


expressions1015101

Part of a statement that represents a value or can be used to calculate a value.


event1015102

A user action, such as a button click, or a system occurrence such as a preset time interval, recognized by a component.

Each component has a list of specific events to which it can respond. Code that is executed when a particular event occurs is called an event handler.


event handler1015103

A form method attached to an event. The event handler executes when that particular event occurs.

When you use the Object Inspector to attach code to a component event, Delphi generates a procedure header and a begin..end block for you. For example, this is the code Delphi generates for a button click event:

procedure TForm1.Button1Click(Sender: TObject);

begin

end;

The code you write inside the begin..end block executes whenever Button1 is clicked.


features1015104

A generic term used to refer the fields of a record, the types, constants, variables and routines of a unit, and the fields, properties, and methods of a class.


field1015105

1.	One possible element of a structured data type (that is, a record or object), a field is an instance of a specific data type. (Compare with property.)

2.	In database terminology, a column of information in a table. A collection of related fields makes up one record. See also record.


file buffer1015106

An area of memory set aside to expedite the transfer of data to and from a file.


file type1015107

A file type refers to the specific data type that a file holds.


filter1015108

Anything used to check or alter data. For example, the file filter in the Save dialog box can be set to show only Pascal files.


filter program1015109

A program that takes output from another program as input and produces an altered, reduced, or verified version of that output.


focus1015110

The component or window that is active in a running application is said to have "focus." Any keyboard input the user enters is directed to that component or window.


formal parameter1015111

An identifier in a procedure or function declaration heading that represents the arguments that will be passed to the subprogram when it is called.

See parameter name for information on a given parameter.


form1015112

To an end user, a form is merely another window. In Delphi, a form is a window that receives components (placed by the programmer at design time, or created dynamically with code at run time), regardless of the intended run-time functionality of the window.


function1015113

A subroutine that computes and returns a value.


function header1015114

Text that gives the name of a routine followed by a list of formal parameters, followed by the function's return type. In a unit, a routine may have a header entered into the interface part, and then again in the implementation part. The second appearance of the header may be an exact duplicate of the header in the interface part, or may be only the name of the routine.


global heap1015115

Memory available to all applications.

Although global memory blocks of any size can be allocated, the global heap is intended only for large memory blocks (256 bytes or more). Each global memory block carries an overhead of at least 20 bytes, and under the Windows standard and 386 enhanced modes, there is a system-wide limit of 8192 global memory blocks, only some of which are available to any given application.

Note:	Delphi suballocates small allocations from large global memory blocks to reduce the liklihood of hitting the system limit. (See HeapLimit, HeapBlock.)


global variable1015116

A variable used by a routine (or the main body of a program) that was not declared by that routine (or a var part of the main body) is considered a global variable by that code. A variable global to one part of a program may be inaccessible to another part of the same program, and hence considered local in that context.


globally unique identifier (GUID)1015117

A GUID is a specific type of universally unique identifier (UUID).  It is a 16 byte (128-bit) binary value that is guaranteed to be unique.


glyph1015118

A bitmap that displays on a BitBtn or SpeedButton component with the component's Glyph property.


grandchild1015119

A class descended from another through one or more intermediate classes. Example: In the following type definition "type E = class(D)", E is the child of D. If D is descended from class C, then E is a grandchild of class C, as well as C's parent, C's parent's parent, and so on, until the root class is reached. C and its ancestors are E's grandparents.


grandparent1015120

A class from which others are descended through one or more intermediate classes. See grandchild.


grid1015121

1.	The evenly spaced dots on the form that aid in placing components during design time (not visible at run time). Control through Options | Environment | Preferences.

2.	In database terminology, an object on a form that enables you to view and edit all the records in a dataset in a spreadsheet-like format. You create a grid with a TDBGrid component.


handling exceptions1015122

Making a specific response to an exception, which then clears the error condition and destroys the exception object.


header1015123

Text that gives the name of a routine followed by a list of formal parameters, followed in the case of a function by the function's return type. In a unit, a routine may have a header entered into the interface part, and then again in the implementation part. The second appearance of the header may be an exact duplicate of the header in the interface part, or may be only the name of the routine.


heap1015124

An area of memory reserved for the dynamic allocation of variables.


heap suballocator 1015125

When allocating a memory large block, the heap manager simply allocates a global memory block using the Windows GlobalAlloc routine.

When allocating a small block, the Object Pascal heap manager allocates a larger global memory block and then divides (suballocates) that block into smaller blocks as required. Allocations of small blocks reuse all available suballocation space before the heap manager allocates a new global memory block, which, in turn, is further suballocated.


help context1015126

A number assigned individually to the controls in a program so that when the user activates Help, the Help system can query the focused control and use the help context as a reference to supply information appropriate to what the user is doing.


hint1015127

Pop-up text that appears when the mouse pointer passes over an object in the user interface at run time. Specified in the Hint property of many visual components.


host type1015128

The particular server being used for a process or series of processes, hence "hosting" the activities.


IDAPI1015129

See BDE.


identifier1015130

A programmer-defined name for a specific item (a constant, type, variable, procedure, function, unit, program, or field).


implementation1015131

The second, private part of a unit that defines how the elements in the interface part (the public portion) of the unit work.


include file (.INC)1015132

An include file (.INC) is a source-code file that is included in a compilation using the {$I filename} compiler directive.

Include files are seldom part of a Delphi project, but can optionally be used.


index1015133

1.	A position within a list of elements.

2.	In database terminology, a sort order for a table associated with a specific field or fields, used to locate records quickly. An index performs the following tasks:

Determines the location of records.

Keeps records in sorted order.

Speeds up search operations.


index type1015134

Specifies the type of elements in an array. Valid index types are all the ordinal types except Longint and subranges of Longint.


inheritance1015135

The assumption of the features of one class by another.


instance1015136

A variable of an object type. More generally, a variable of any type. Actual memory is allocated.


integer1015137

A numeric variable type that is a whole number in the range -32,768 to +32,767.


integrated debugger1015138

The integrated debugger is contained within the Integrated Development Environment. This debugger lets you debug your source code without leaving Delphi. The functionality of this debugger can be reached through the Run and View menus.


interface1015139

The first, public part of a unit that describes the constants, types, variables, procedures, and functions that are available within it.


key1015140

A field or group of fields in a table, used to order records. A key has three effects:

The table is prevented from containing duplicate records.

The records are maintained in sorted order based on the key fields.

A primary index is created for the table.


label1015141

An identifier that marks the target for a goto statement.


language driver1015142

Determines a table's sort order and available character set. The BDE Configuration Utility enables you to specify the default language driver for tables.


late binding1015143

When the addess used to call virtual methods or dynamic methods is determined at run time.


linking1015144

The process of turning compiled source code into an executable file. At the linking stage resources are bound into the executable.


literal value1015145

A value that appears in the actual source code, such as the string "Hello, World" or the numeral 1 (as opposed to a calculated value or a declared constant).


local heap1015146

Memory available only to your application or library.

It exists in the upper part of an application's or library's data segment.

The total size of local memory blocks that can be allocated on the local heap is 64K minus the size of the application's stack and static data. For this reason, the local heap is best suited for small memory blocks (256 bytes or less). The default size of the local heap is 8K, but you can change this with the $M compiler directive.


local symbol information1015147

Information used by the IDE to debug a routine. Local symbol information must be enabled in the Project Options dialog box (Options | Project). Enabled by default in new Delphi installations.


local variable1015148

A variable declared within a procedure or function.


lock1015149

A device that prevents other users from viewing, changing, or locking a table while one user is working with it.


logic error1015150

Logic errors occur when your program statements are valid, but the actions they perform are not the actions you intended. For example, logic errors occur when variables contain incorrect values, when graphic images don�t look right, or when the output of your program is incorrect.


Longint (type)1015151

A 4-byte integer, able to store integers in the range -2,147,483,648 to +2,147,483,647.


lookup table1015152

A secondary table that enables database systems to use a small code field to enable many records in a primary table to refer to information stored in the lookup table.

This can be used as a means of ensuring that values entered in a primary table are legitimate values, thus safeguarding data integrity.


loop1015153

A statement or group of statements that repeat until a specific condition is met.


main form1015154

At design time, the first form created in or added to a project. The form designated as the main form can be changed in the Project Options dialog box (Options | Project | Forms). The main form is usually the first displayed at run time, and usually the principal form displayed throughout the execution of the program.


master table1015155

In a multi-table relationship, the primary table of your data model. If you have only one table in your data model, that table is the master table. In a multi-table data model, the master table is the one pointing to other tables. For example, in the following data model, all of the tables except VENDORS.DB are master tables.


method1015156

Procedure or function associated with a particular object.


method identifier1015157

The identifying string or dynamic index of a method.


method pointer1015158

A pointer to a specific method in a specific object.


multiple document interface (MDI) application1015159

An application whose interface consists of a main application window, called the frame window, that can contain multiple child windows, or documents. The child window's document title merges with the parent window's title bar when the child window is maximized.


modal1015160

The run-time state of a form designed as a dialog box in which the user must close the form before continuing with the application. A modal dialog box restricts access to all other areas of the application. See Help for the ShowModal method for more information.


modeless1015161

The run-time state of a form designed as a dialog box in which the user can switch focus away from the dialog box without first closing it. See Help for the Show method for more information.


module1015162

A self-contained routine or group of routines. A unit is an example of a module.


nil1015163

A pointer value referencing nothing. A pointer must be assigned a memory address in order to be meaningfully and safely used.

Note:	Referencing a pointer having a nil value causes a General Protection Fault exception.


nonvisual component1015164

A component that appears at design time as a small picture on the form, but either has no appearance at run time until it is called (like TSaveDialog) or simply has no appearance at all at run time (like TTimer).


nonwindowed control1015165

A nonwindowed control is a control that cannot receive the focus, that cannot be the parent of other controls, and which does not have a window handle.


object files (.OBJ)1015166

An intermediate machine-code file usually produced with an assembler. It is linked with a project or unit using the $L filename compiler directive.

Functions residing in .OBJ files are declared EXTERNAL in Pascal declarations. Object files (.OBJ) are seldom a part of a Delphi project.


object instance variable1015167

The identifier created internally for an instance of an object.


object type1015168

A class.


OLE1015169

Object Linking and Embedding is a method for sharing complex data among applications. With OLE, data from a server application is stored in a container application. The data is stored in an OLE Object.


OLE container1015170

An application that can contain an OLE object. In Delphi, an OLE container application has a TOLEContainer component.


OLE object1015171

The data shared by an OLE server and OLE container. An OLE object can be linked or embedded in the container application. The data for linked objects are stored in an external file; embedded objects are stored in the container application.

Examples of OLE objects are documents, spreadsheets, pictures, and sounds.


OLE server1015172

An application that can create and edit an OLE object.


ordinal (type)1015173

Any Object Pascal type consisting of a closed set of ordered elements.


override1015174

Redefine an object method in a descendant object type.


owner1015175

An object responsible for freeing the resources used by other (owned) objects.


package1015176

A special dynamic-link library used by Delphi applications, the Delphi IDE, or both. Runtime packages provide functionality when a user runs an application. Design-time packages are used to install components in Delphi�s IDE and to create special property editors for custom components.


parameter1015177

A variable or value that is passed to a function or procedure.


parent1015178

1.	The immediate ancestor of a class, as seen in its declaration. Example: In "type B = class(A)", class A is the parent of class B.

2.	Parent property: the component that provides the context within which a component is displayed.


pixel1015179

Any of the individual colored dots that make up an image on the screen. Derived from the words "picture element."


pointer1015180

A variable that contains the address of a specific memory location.


power set1015181

The set of all possible subsets of values of the base type including the empty set.


primary index1015182

An index on the key fields of a table. An index performs the following tasks:

Determines the location of records.

Keeps records in sorted order.

Speeds up search operations.

A primary index typically has a requirement of uniqueness--that is, no duplicate keys can exist.


private1015183

The keyword indicating the beginning of a class declaration.


private part1015184

Elements declared in this part of a class declaration can be used exclusively within the module that contains the class declaration. Outside that module they are unknown and inaccessible.


procedure1015185

A subprogram that can be called from various parts of a larger program. Unlike a function, a procedure returns no value.


procedure declaration1015186

The procedure declaration is the first occurrence of the procedure header that appears in a unit or project.


procedure header1015187

Text that gives the name of a routine followed by a list of formal parameters. In a unit, a routine may have a header declared in the interface part, and then again in the implementation part. The second appearance of the header may be an exact duplicate of the header in the interface part, or may be only the name of the routine.


program1015188

An executable file. Less formally, a program and all the files it needs to run. Contrast with application.


project1015189

The complete catalogue of files and resources used in building an application or DLL. More specifically, the main source code file of the programming effort, which lists the units that the application or DLL depends on.


project directory1015190

The directory in which the project file resides.


project file1015191

The file that contains the source code for a Delphi project. This file has a .DPR extension. It lists all the unit files used by the project and contains the code to launch the application.


property1015192

 A feature that provides controlled access to methods or fields of an object. A published property may also be stored to a file.


protected1015193

Used in class type definitions to make features visible only to the defining class and its descendants.


protected block1015194

The try block of a try...except or try...finally statement.


public1015195

Used in class type definitions to make features visible to clients of that class.


published1015196

Used to make features in class type definitions streamable. Streamable features are visible at design time.


qualified identifier1015197

An identifier that contains a period, that is, includes a qualifier. A qualified identifier forces a particular feature (of an object, record or unit) to be used regardless of other features of the same name that may also be visible within the current scope.


qualified method identifier1015198

An object-type identifier, followed by a period (.), followed by a method identifier. Like any other identifier, you can prefix a qualified method identifier with a unit identifier and a period.


qualifier1015199

An identifier, followed by a period (.), that precedes a method or other identifier to specify a particular symbol reference.


query1015200

A way to retrieve data from your tables. A query can examine the data in a single table or in several tables.


raise1015201

Raising an exception means constructing an exception object to signal an error or other exception condition. The application then must handle the exception.


real1015202

A number represented by floating-point or scientific notation.


record1015203

1.	An instance of a record type.

2.	In database terminology, a horizontal row in a table that contains a group of related fields of data.


record type1015204

A structured data type that consists of one or more fields.


recursion1015205

A programming technique in which a subroutine calls itself. Use care to ensure that a recursion eventually exits. Otherwise, an infinite recursion will cause a stack fault.


relational database1015206

A database management model in which data is stored as rows (records) and columns (fields), and in which the data in one table can access the data in other tables by means of a common data field. The database structure can be used to create one-to-many and many-to-one relationships with data elements.


report1015207

Organized summary or detail information that is presented to the end user either as a printed document or an online display.


root class1015208

A class that itself has no ancestors, and from which all other classes are descended. In Delphi, the root class is TObject.


routine1015209

A procedure or function.


row1015210

The horizontal component of a table, sometimes called a record. A row contains one value for each column in a related group of columns in a table. See also column.


run time1015211

Period when the application you design is running.


run-time error1015212

An error that occurs when the application runs, as opposed to a compile-time error.


run-time library1015213

The standard procedures and functions available to all Object Pascal programs.


run-time only1015214

Routines, properties, events, or components that can be be modified, called, or seen only while your application is running (as opposed to design time).


run-time package1015215

A special dynamic-link library used by Delphi applications to provide functionality when a user runs an application.


scalar type1015216

Any Object Pascal type consisting of ordered components.


scope1015217

The visibility of an identifier to code within a program or unit.


separator1015218

A blank (space) or a comment. Object Pascal treats a comment as a space.


separator bar1015219

A line inserted between menu items. A dash character (-) entered in the Caption property of a new item in the menu designer creates a separator bar at the current position.


set1015220

A collection of zero or more elements of a certain scalar or subrange base type


short-circuit evaluation1015221

Strict left-to-right evaluation of a Boolean expression where evaluation stops as soon as the result of the entire expression is evident. This model guarantees minimum code execution time, and usually minimum code size.


Shortint1015222

A one byte type capable of holding any whole number value from -128 to +127.


sizing handles1015223

The small black rectangles that appear on the perimeter of a component, form or window when selected. You drag them to resize the object.


source code1015224

The line-by-line statements written by the developer of a computer program using an appropriate editing tool and following the syntax rules for a particular programming language.


splash screen1015225

A form you design to "introduce" your application, and which appears immediately at run time while the application main form and secondary forms are being loaded in memory, or while a database server connection is being established. See also main form.


SpeedMenu1015226

A local menu on an object which you can access by right-clicking with a pointing device.


SQL1015227

Structured Query Language, abbreviated SQL and commonly pronounced "sequel." A relational database language used to define, manipulate, search, and retrieve data in databases.


SQL table1015228

A table on a database server defined by SQL.


stack1015229

An area of memory reserved for storing local variables. Also keeps track of program execution and subroutine calls.


statement1015230

The simplest unit in a program; statements are separated by semicolons.


static1015231

Resolved at compile time, as are calls to procedures and methods.


step over1015232

A debugger command that executes a program one line at a time, stepping over procedures while executing them as a single unit. Contrast with trace into.


string1015233

A sequence of characters that can be treated as a single unit of data.


string list1015234

A flexible collection of strings and (potentially) the objects associated with them.


subrange1015235

Any specified contiguous portion of a scalar type.


switch directive1015236

A compiler directive that turns compiler features on or off depending on the state (+ or -) of the switch. For example, {F+} turns the Force Far calls directive on; {F-} turns it off.


symbol1015237

Any identifier. Symbols include reserved words.


table1015238

A structure made up of rows (records) and columns (fields) that contains data.


tag field1015239

A Longint storage for a specific instance of a component to be used as wanted by the programmer.


TDBDataset1015240

A descendant of TDataset that includes the functionality needed to connect to a database, handle passwords, and perform other tasks associated with database connectivity.

You cannot instantiate an object of TDataset directly; you instantiate TTable, TQuery, or another TDataset descendant.


template1015241

A predesigned project or form that serves as a starting point for your application design.


trace into1015242

A debugger command that executes a program one line at a time, tracing into procedures which were compiled with debug information and following the execution of each line. Contrast with step over.


typecasting1015243

The forcing of the compiler to treat an expression of type X as though it were an expression of type Y.

Using AS to typecast object instances causes generation of code to validate the compatibility of the typecast at run time. Normal typecasts are evaluate at compile time and are not validated at run time.


type1015244

A description of how data should be stored and accessed. Contrast with variable--the actual storage of the data.


type compatibility1015245

An instance may be used in place of or assigned to another type it is said to be compatible with.

Integer types are all cross-compatible. A descendant class instance is type-compatible with a variable of an ancestor type. Sibling classes are not type-compatible, nor are ancestors type-compatible with their descendants.


typed constant1015246

A variable that is given a default value upon startup of the application. All global variables occupy a constant space in memory.


type definition1015247

The specification of a non-predefined type. Defines the set of values a variable can have and the operations that can be performed on it.


unit1015248

A independently compileable code module consisting of a public part (the interface part) and a private part (the implementation part).

Every form in Delphi has an associated unit.

The source code of a unit is stored in a .PAS file. A unit is compiled into a binary symbol file with a .DCU extension. The link process combines .DCU files into a single .EXE or .DLL file.


untyped file1015249

Low-level I/O (input/output) channels that let you directly access any disk file regardless of its internal format.


untyped pointer1015250

A pointer that does not point to any specific type. An untyped pointer cannot be referenced without a typecast. (Also see typecast.)


unqualified identifier1015251

An identifier that contains no periods, that is, an identifier with no qualifier. The semantics of an unqualified identifier depend on the current scope. Example: "Create" is an unqualified identifier that will call any routine called "Create" within the current scope (or cause a compile error if no such routine is visible) but "TForm.Create" will call the specific "Create" method which is a feature of TForm. See qualifier.


use count1015252

An internal variable that Windows uses to determine whether or not a DLL should stay in memory. A DLL stays in memory while its use count is greater than zero.

Windows increments Use Count every time an application loads a DLL and decrements whenever an application frees the DLL.


user-defined1015253

Said of a type that is defined by a programmer and not inherently part of the Pascal language. This includes any type definitions you may code or definitions provided by Borland, or any other source.


value parameter1015254

A procedure or function parameter that is passed by value; that is, the value of a parameter is copied to the local memory used by the routine and therefore, changes made to that parameter are local.

See variable parameter, const parameter.


variable parameter1015255

A subroutine parameter that is passed by reference. Changes made to a variable parameter remain in effect after the subroutine has ended. See value parameter, const parameter.


variable1015256

An identifier that represents an address in memory, the contents of which can change at run time.


virtual1015257

Calls are resolved at run time by name.


visual component1015258

A component that is visible, or can be made visible on a form at run time.


watches1015259

A watch expression lets you track the values of program variables or expressions as you step over or trace into your code. Use the Watch List window to view the currently set watches.

As you step through your program, the value of the watch expression will change if your program updates any of the variables contained in the watch expression.


window handle1015260

A number assigned by Windows to a control that must be used to request services for that control from the Windows API.


windowed control1015261

A control that can receive the focus, that can own other controls, and which does have a window handle.


word1015262

In Delphi, A location in memory occupying 2 adjacent bytes; the storage required for a variable of type integer or word. Also, a predefined data type with a range of 0 to 65535.


wrapper1015263

An object, routine, group of objects, or group of routines designed to encapsulate some functionality for the programmer usually for some perceived benefit. VCL is an object-oriented wrapper for the Windows API.


z-order1015264

The conceptual distance of an object from the surface of the screen. Whether or not a control is covered by other controls depends on its z-order relative to those controls.


マウスイベントとは
マウスイベントとは1016001

参照

Delphi では 3 つのマウスイベントが定義されています。

OnMouseDown

OnMouseMove

OnMouseUp

Delphi アプリケーションがマウスアクションを検出すると，対応するイベントに定義したイベントハンドラが呼び出され，5 つのパラメータが渡されます。これらのパラメータの情報はイベントへの応答をカスタマイズするために使います。5 つのパラメータを次に示します。

パラメータ	意味

Sender	マウスアクションを検出したオブジェクト

Button	どのボタンが関係したかを示す mbLeft，mbMiddle，mbRight のいずれか

Shift	マウスアクション時の〔Alt〕，〔Ctrl〕，〔Shift〕の状態を示す

X，Y	イベントが発生した場所の座標

ほとんどの場合，マウスイベントハンドラでもっとも重要な情報は座標ですが，どのマウスボタンによってイベントが発生したかを調べるために Button をチェックしなくてはならない場合もあります。

メモ:	Delphi はどのマウスボタンが押されたかを調べるときに Microsoft Windows と同じ設定を使用します。したがって，デフォルトの「左」と「右」のマウスボタンを交換した (マウスの右ボタンが左ボタンになるようにした) 場合，右ボタンをクリックすると Button パラメータの値として mbLeft が渡されます。


参照1016002

マウスへの応答


フォームオブジェクトへのフィールドの追加
フォームオブジェクトへのフィールドの追加1016003

参照	例

フォームにコンポーネントを追加すると，そのコンポーネントを表すフィールドがフォームオブジェクトに追加されます。このフィールドの名前を使ってコンポーネントを参照できます。フォームのユニットの最上部にある型宣言を編集することによって，独自のフィールドをフォームに追加できます。

独自のフィールドを追加すると，そのフォームに関連付けたすべてのイベントハンドラに対してグローバルな変数を宣言する手段が得られます。

オブジェクトにフィールドを追加するには

宣言部の最後で public 指令の後にフィールドの識別子と型を指定することによって，オブジェクトの型定義を編集する

Delphi はコンポーネントを表すすべてのフィールドと，イベントに応答するすべてのメソッドを public 指令の前に置きます。


参照 1016004

フォームオブジェクトへのメソッドの追加

フォームの型宣言の変更


例1016005

次のコードは論理型のフィールド Drawing を Form1 の宣言に追加します。

type

  TForm1 = class(TForm)

    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

    procedure FormMouseMove(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

  public

    Drawing: Boolean;	{ ボタンが押されたかどうかを追跡するフィールド }

  end;


ツールバーへのスピードボタンの追加
ツールバーへのスピードボタンの追加1016006

参照

スピードボタンはツールバー上の図形表示ボタンで，メニューコマンドやマクロのショートカットを表すために使います。

スピードボタンをパネルに追加すると，パネルはスピードボタンのコンテナになるため，パネルを移動したり非表示にすることによってスピードボタンも移動し非表示になります。

ツールバーにスピードボタンを追加するには

ツールバーを表すパネルにスピードボタンコンポーネントを配置する

ツールバーのデフォルトの高さは 41 で，スピードボタンのデフォルトの高さは 25 です。各ボタンの Top プロパティを 8 に設定すると，ボタンは縦に中央揃えされます。デフォルトのグリッド設定を使うとスピードボタンはグリッド位置に自動的に配置されます。


参照1016007

スピードボタンへのグリフの割り当て

スピードボタンのグループの作成

スピードボタンの初期条件の設定

ツールバーパネルへのスピードボタンの追加


スピードボタンへのグリフの割り当て
スピードボタンへのグリフの割り当て1016008

参照

各スピードボタンにはボタンがする操作をユーザーに対して示すためのグリフと呼ばれるグラフィックイメージが必要です。スピードボタンにイメージを 1 つだけ指定した場合，ボタンはそのイメージを処理してボタンが押されている，押されていない，選択されている，使用不可であるのいずれかを表します。必要に応じて，各状態ごとに別の特有のイメージを指定できます。

通常，グリフは設計時に割り当てます。ただし，実行時に別のグリフを割り当てることもできます。

スピードボタンにグリフを割り当てるには

1.	スピードボタンを選択します。

2.	オブジェクトインスペクタで Glyph プロパティを選択します。

3.	Glyph の横の値列をダブルクリックします。

［画像の設定］が開きます。

4.	画像の設定で［読み込み(L)］をクリックします。

［画像の読み込み］ダイアログボックスが開きます。

5.	ボタンに配置するイメージが保存されている .BMP ファイルを選択し，［OK］をクリックします。

［画像の読み込み］ダイアログボックスが閉じ，選択したビットマップイメージが画像エディタに表示されます。

6.	［OK］をクリックすると画像エディタが閉じます。


参照1016009

ツールバーへのスピードボタンの追加

スピードボタンのグループの作成

スピードボタンの初期条件の設定


スピードボタンの初期条件の設定
スピードボタンの初期条件の設定1016010

参照

スピードボタンの外観からユーザーはボタンの状態と目的を表す情報がわかります。スピードボタンにはキャプションがないため，ユーザーが簡単に理解できるような適切なイメージをボタンに表示することが重要です 。スピードボタンへのグリフの指定がこれに大きく関係します。

実行時にユーザーがスピードボタンを選択すると，デフォルトではボタンは押された状態で表示され，ユーザーがボタンから指を離すと上がった状態に戻ります。ボタンをトグルにするかグループ化することによって，ユーザーがスピードボタンを選択したときにボタンが押されたまま (下がったまま) の状態になるよう指定できます。トグルボタンはユーザーがそのボタンを選択するたびに押された状態と上がった状態を切り替えます。

グループ化しないスピードボタンをトグルにするには

1.	AllowAllUp プロパティを True に設定します。

2.	GroupIndex プロパティをゼロ以外の値に設定します。

アプリケーションでスピードボタントグルを初めて表示するとき，押された状態で表示するよう指定できます。たとえば，ボタングループの中でそのボタンがデフォルト選択であることを示す場合などです。

スピードボタンの初期状態を押された状態にするには

1.	スピードボタンをトグルにします (前述の手順を参照)。

2.	Down プロパティを True に設定します。

ほかのコンポーネントと同様に，スピードボタンを使用不可にすることによって，初期状態としてまたはアプリケーション実行中の任意の時点でスピードボタンを使えないようにできます。

スピードボタンを使用不可として表示するには

Enabled プロパティを False に設定する

メモ:	Enabled を False に設定すると，スピードボタン上に表示されるビットマップは自動的に淡色表示になります。スピードボタンにグラフィックが含まれない場合，Enabled を False に設定してもユーザーに対してそのボタンが使えないことを知らせる視覚表示は与えられません。ユーザーが実行時にそのボタンを選択しても，ボタンは応答しません。


参照1016011

ツールバーへのスピードボタンの追加

スピードボタンへのグリフの割り当て

スピードボタンのグループの作成


スピードボタンのグループの作成
スピードボタンのグループの作成1016012

参照

スピードボタンのグループを作成するときにはフォーム内またはコンテナコンポーネント内にボタンを視覚的に関連付けるだけで，それ以上の指定は必要ありません。ただし，実行時に相互依存的に動作するスピードボタングループを作成することもできます。

実行時にユーザーがスピードボタンを選択すると，デフォルトではボタンは押された状態で表示され，ユーザーがボタンを離すと上がった状態に戻ります。スピードボタンをグループ化することによって，ユーザーがボタンを選択した後そのボタンがグループ内で押されたまま (下がったまま) の状態になるよう指定できます。

メモ:	グループ化していないスピードボタンの場合は，トグルにすると押された状態のままで表示できます。

スピードボタンをグループ化する場合，グループ内では常に 1 つのボタンが押された状態になるように指定できます。反対に，グループ内のすべてのボタンを上がった状態にすることもできます。

任意の個数のスピードボタンを 1 つのグループに関連付けるには

グループに含めるボタンをすべて選択し，グループ全体を選択した状態で，GroupIndex プロパティをゼロ以外の値に設定する (GroupIndex のデフォルト値はゼロで，スピードボタンの間にはグループ関係は設定されない)

既存のグループにはスピードボタンをいつでも追加できます。スピードボタンの GroupIndex プロパティをグループの GroupIndex プロパティと同じ値に設定すると追加できます。フォーム上で，またはフォームの同じコンテナ内で同じ GroupIndex 値を持つすべてのスピードボタンは，実行時にグループとして連動します。

グループ内のすべてのボタンを上がった状態で表示するには

グループ内のすべてのスピードボタンの AllowAllUp プロパティを True に設定する

グループ内の 1 つのスピードボタンの AllowAllUp を True に設定すると，同じグループ内のほかのすべてのスピードボタンの AllowAllUp が自動的に True に設定されます。


参照1016013

ツールバーへのスピードボタンの追加

スピードボタンへのグリフの割り当て

コンテナコンポーネント内でのスピードボタンのグループ化

スピードボタンの初期条件の設定


コンテナコンポーネント内でのスピードボタンのグループ化
コンテナコンポーネント内でのスピードボタンのグループ化1016014

参照

グループ化するコンポーネントをコンテナコンポーネント (パネルなど) に置くと，設計時に移動やコピー，削除などの操作でこれらをグループとして扱うのが簡単になります。コンテナコンポーネントのプロパティを使って，境界を高くした状態または低くした状態で表示するなど視覚的効果を与えることもできます。

スピードボタンをグループとして動作させるためにはコンテナ内に置く必要はありません。GroupIndex プロパティの設定によって，実行時にどのボタンが連動するかが決まります。ゼロ以外の GroupIndex 値の各種集合を設定することによって，複数のスピードボタングループを作成できます。フォーム上で，またはフォームの同じコンテナ内で同じ GroupIndex 値を持つすべてのスピードボタンが実行時にグループとして連動します。


参照1016015

ツールバーへのスピードボタンの追加

ツールバーとクールバーの操作

スピードボタンへのグリフの割り当て

スピードボタンのグループの作成

スピードボタンの初期条件の設定


フォームオブジェクトへのメソッドの追加
フォームオブジェクトへのメソッドの追加1016016

参照	例

複数のイベントハンドラが同じコードを使う場合，繰り返し使われるコードをすべてのイベントハンドラが共有可能なメソッドに移動することによって，アプリケーションの効率を高めることができます。

フォームにメソッドを追加するには

1.	メソッド宣言をフォームオブジェクトに追加します。

この宣言はフォームオブジェクト宣言の終わり部分の public 部または private 部に追加できます。コードがイベントの処理方法だけを共有する場合は，共有メソッドを private にするほうが安全です。

2.	フォームユニットの implementation 部にメソッドの実装を記述します。

メソッド実装のヘッダーは宣言と正確に一致しなくてはならず，同じパラメータを同じ順序で記述しなくてはなりません。


参照1016017

フォームオブジェクトへのフィールドの追加

フォームの型宣言の変更


例1016018

次のコードはフォーム DrawShape にメソッドを追加し各ハンドラからこのメソッドを呼び出すことによって，マウスイベントハンドラから繰り返し使われる図形描画コードを省略します。

1.	DrawShape の宣言をフォームオブジェクトの宣言に追加します。

type

  TForm1 = class(TForm)

    ...	{ 他のフィールドとメソッド }

  public

    { パブリック宣言 }

    procedure DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);

  end;

2.	DrawShape の実装をユニットの implementation 部に記述します。

implementation

{$R *.DFM}

...	{ 他のメソッドの実装 }

procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode:
  TPenMode);

begin

  with Image.Canvas do

  begin

    Pen.Mode := AMode;

    case DrawingTool of

      dtLine:

        begin

          MoveTo(TopLeft.X, TopLeft.Y);

          LineTo(BottomRight.X, BottomRight.Y);

        end;

      dtRectangle: Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X,
        BottomRight.Y);

      dtEllipse: Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X,
        BottomRight.Y);

      dtRoundRect: RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X,
        BottomRight.Y,

        (TopLeft.X - BottomRight.X) div 2, (TopLeft.Y -
          BottomRight.Y) div 2);

    end;

  end;

end;

3.	ほかのイベントハンドラを変更し DrawShape を呼び出すようにします。

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  DrawShape(Origin, Point(X, Y), pmCopy);	{ 最終的な図形を描画 }

  Drawing := False;

end;

procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then

  begin

    DrawShape(Origin, MovePt, pmNotXor);	{ 前の図形を消去 }

    DrawShape(Origin, Point(X, Y), pmNotXor);	{ 現在の図形を描画 }

  end;

end;


非表示のツールバーの追加
非表示のツールバーの追加1016019

参照

ツールバーは常に表示する必要はありません。実際には，使用可能なツールバーが複数あり，ユーザーが利用するときにだけ表示すると便利です。複数のツールバーを持つフォームを作成し，そのうちの一部またはすべてのツールバーを非表示にできます。

非表示のツールバーを作成するには

1.	ツールバーをフォームに追加します (Align を alTop に設定してください)。

2.	パネルの Visible プロパティを False に設定します。

ツールバーは設計時には変更できるように表示されますが，実行時にはアプリケーションが明示的に表示を指定しない限り非表示になります。


参照1016020

ツールバーの表示と非表示


ツールバーの表示と非表示
ツールバーの表示と非表示1016021

参照

アプリケーションに複数のツールバーを作成する場合，すべてのツールバーが同時に表示されてフォームが混乱するような状況は避ける必要があります。また，ユーザーによってはツールバーをまったく必要としない場合があります。他のすべてのコンポーネントと同様に，実行時にツールバーを表示するか非表示にするかをコードで指定できます。

実行時にツールバーを非表示または表示するには

Visible プロパティを False または True に設定する。通常は特定のユーザーイベントへの応答またはアプリケーションの操作モードの変更への応答として設定する

一般に各ツールバーにはクローズボタンに類するボタンを入れます。ユーザーがそのボタンをクリックしたとき，アプリケーションは対応するツールバーを非表示にします。


参照1016022

非表示のツールバーの追加


ステータスラインパネルの配置
ステータスラインパネルの配置1016023

参照

一般に，ステータスラインはフォームの下部に表示されます。ステータスラインパネルをフォームの下部に揃える場合，配置とサイズ変更は自動調整されます。

フォームにステータスラインパネルを追加するには

1.	パネルコンポーネントをフォームに配置します。

2.	パネルの Align プロパティを alBottom に設定します。

3.	パネルのキャプションをクリアします。

ステータスラインパネルを追加したら，このパネルを複数のステータスパネルに分割できます。分割しない場合は，BevelInner プロパティと BorderWidth プロパティを設定して３次元効果を追加できます。より小さいパネルのコンテナとしてだけ機能するパネルでは通常これらのプロパティを変更しません。

パネル内でテキストを揃えることもできます。デフォルトではパネルのキャプションは中央揃えされますが，ステータスラインでは Align を alLeft に設定することがよくあります。


参照1016024

ステータスバー

パネルの分割

３次元パネルの作成

ステータスラインの更新


パネルの分割
パネルの分割1016025

参照

ステータスラインとして使うパネルなどでは，パネルを複数の独立した領域に分割する場合があります。1 つのパネル内でテキストの形式を慎重に設定して同様の効果を得ることもできますが，それぞれ独立したパネルを使うともっと効率的です。

パネル内に別のパネルを作成するには

1.	パネル内に新しいパネルを配置します。

2.	新しいパネルに希望する３次元効果を設定します。

3.	新しいパネルの Align プロパティを alLeft に設定します。

4.	新しいパネルの右側を移動して幅を調整します。

5.	新しいパネルのキャプションをクリアします。

6.	必要に応じてその他のパネルについて手順 1 ～ 5 を繰り返します。

左揃えの新しいパネルを元のパネルに追加すると，追加したパネルはそれぞれの右側で揃います。最後のパネルについては，元のパネルの残りのスペースをすべて使って表示されるように，Align を alLeft ではなく alClient にするといいでしょう。


参照1016026

ステータスラインパネルの配置

３次元パネルの作成

ステータスラインの更新


３次元パネルの作成
３次元パネルの作成1016027

参照

ステータスライン情報を表示するために使うパネルコンポーネントには通常３次元効果を持たせます。デフォルトでは，すべてのパネルは外部ベベルを持ち，わずかに持ち上げられたような外観になります。反対に，内側に表示されるテキストを押し下げて強調し，パネルがテキストの回りの枠のように見えるようにすると通常は見栄えがよくなります。

テキストが押し下げられて見えるような効果を与えるには，BevelInner と BorderWidth の 2 つのプロパティを変更します。

パネルを「彫り込んだ」ように見せるには，BevelInner を bvLowered に設定する

内部ベベルと外部ベベルの間のスペースを変更するには，BorderWidth プロパティを変更する。BorderWidth を 2 に設定すると見栄えがよくなる

内部ベベルと外部ベベルの組み合わせによってテキストの回りの枠が作成されます。


参照1016028

ステータスラインパネルの配置

パネルの分割

ステータスラインの更新


ステータスラインの更新
ステータスラインの更新1016029

参照	例

フォームにステータスラインを追加したら，ステータスライン情報を更新する必要があります。パネルのキャプションテキストはいつでも設定でき，これによってグラフィックアプリケーションでカーソル位置を示したり，表計算アプリケーションで選択したセルを示すなど，ユーザーに提供したい情報を表示できます。

ステータスラインパネルを更新するには

パネルの Caption プロパティを使ってユーザーに対して表示する情報を設定する

特定のパネルに表示されるステータスに影響を与えるイベントハンドラにこのコードを追加します。


参照1016030

ステータスラインパネルの配置

パネルの分割

３次元パネルの作成

OnHint イベント


例1016031

有効なステータスラインを更新する基本手順は次のようになります。

1.	メインフォームの宣言の public セクションにメソッドの宣言を追加します。

procedure ShowHint(Sender: TObject);

2.	メインフォームの OnCreate イベントのイベントハンドラに次の代入文をコーディングします。

Application.OnHint := ShowHint;

3.	ShowHint メソッドに次のコードを記述します。

procedure TForm1.ShowHint(Sender: TObject);

begin

  Panel1.Caption := Application.Hint;   { Panel1 はステータスライン }

end;

有効なステータスラインの作成についての詳細は OnHint イベントの例を参照してください。


ビットマップでの描画
ビットマップでの描画1016032

参照

フォーム上に直接描画しなくてはならないことはあまり多くありません。それよりもアプリケーションではコピー，印刷，および保存などの操作でイメージを柔軟に扱えるビットマップに描画する場合の方が多くあります。Delphi の Image コンポーネントはビットマップを含むことができるため，フォーム上にビットマップを簡単に表示できます。

記述する描画コードをフォームではなくビットマップに適用するには，次の 2 つのことが必要です。

フォームの Canvas ではなく Image コンポーネントの Canvas を使う

Image コンポーネントの該当するイベントにイベントハンドラをアタッチする

アプリケーションの描画対象を Image コンポーネントのビットマップに移動した後は，印刷，クリップボード操作，ビットマップファイルの読み込み，保存操作などを簡単に追加できます。

さらに，ビットマップはフォームと同じサイズである必要はなく，小さくても大きくてもかまいません。フォームにスクロールボックスコンポーネントを追加しイメージをその中に配置すると，フォームより大きいビットマップ，さらには画面より大きいビットマップ上に描画できます。

スクロール可能な描画ビットマップを追加するには，次の 2 つの手順が必要です。

スクロール可能領域の追加

Image コンポーネントの追加


参照1016033

設計時のイメージのロード

実行時の描画用の領域の提供


スクロール可能領域の追加
スクロール可能領域の追加1016034

参照

アプリケーションが表示する情報が特定の領域内に表示しきれない場合が数多くあります。リストボックスやメモなどのいくつかのコンポーネントは，内容を自動的にスクロールできます。しかしほかのコンポーネントや，場合によってはコンポーネントが満載されたフォームでは，スクロール可能として設定する必要があります。Delphi は ScrollBox コンポーネントによってこのようなスクロール領域を作成する手段を提供します。

スクロールボックスはほかのコンポーネントを含むことができるという点でパネルやグループボックスに似ています。しかし，スクロールボックスは必要になるまで通常は表示されません。スクロールボックスに含まれるコンポーネントがスクロールボックスの表示領域に表示しきれない場合，自動的に 1 つまたは 2 つのスクロールバーが表示され，ユーザーはそれを使って表示領域の外側にあるコンポーネントを表示および使用可能な位置に移動できます。

スクロール領域を作成するには

フォームに ScrollBox コンポーネントを配置し，そのコンポーネントの境界をスクロールさせたい領域に合わせて設定する

スクロールボックスの Align プロパティを使うと，スクロールボックスの領域をフォームまたはフォームの一部に合わせて調整できます。たとえば，Align を alClinet に設定するとスクロールボックスはフォームのクライアント領域全体を占めます。


参照1016035

ビットマップでの描画

フォームへの Image コンポーネントの追加


Image コンポーネントの追加
Image コンポーネントの追加1016036

参照

Delphi の Image コンポーネントは一種のプレースホルダコンポーネントです。このコンポーネントを使うと，フォーム上でビットマップやメタファイルなどの画像オブジェクトを含める領域を指定できます。イメージのサイズは手動で設定するか，Image コンポーネントが実行時に画像のサイズに合わせて調整するよう設定できます。

Image コンポーネントは常に表示しておく必要のないビットマップを保持したり，アプリケーションがほかの画像を生成するために必要とするビットマップを保持するためにも使えます。

コンポーネントの配置

Image コンポーネントはフォーム上のどの位置にでも配置できます。AutoSize を True に設定した場合，左上隅を考慮する必要があります。この位置はコンポーネントのサイズが変わっても変化しないからです。Image コンポーネントをビットマップのための非表示ホルダとして使う場合，この Image コンポーネントは非表示コンポーネントと同様にどこにでも配置できます。

初期画像の設定

Image コンポーネントが常に特定の画像を保持する場合，設計時に Picture プロパティを設定できます。実行時にファイルからコンポーネントに画像をロードすることもできます。またグラフィックアプリケーションなどでは，Image コンポーネントを使ってユーザーが描画可能な領域を提供することもできます。描画用の空白のビットマップを用意するには，実行時にそのビットマップを作成します。詳細は実行時の描画用の領域の提供を参照してください。


参照1016037

Image コントロールの追加

イメージのロード


実行時の描画用の領域の提供
実行時の描画用の領域の提供1016038

参照	例

Image コンポーネントを使って空白のビットマップを配置することにより，実行時にユーザーが描画するための領域を提供できます。

アプリケーション起動時に空白のビットマップを作成するには

1.	Image コンポーネントを含むフォームの OnCreate イベントにハンドラを割り当てます。

2.	ビットマップオブジェクトを作成します。

3.	Image コンポーネントの Picture.Graphic プロパティにビットマップオブジェクトを割り当てます。

ビットマップを画像の Graphic プロパティに割り当てることによって，ビットマップのオーナーシップが画像オブジェクトに与えられます。画像オブジェクトが廃棄されるときにビットマップが自動的に廃棄されるので，ビットマップオブジェクトを廃棄するコードを指定する必要はありません。画像には別のビットマップを割り当てることもでき，その時点で古いビットマップは廃棄され，新しいビットマップが制御の対象になります。


参照1016039

Image コントロールの追加

ファイルからの画像のロード

画像の置換


例1016040

次に示すコードは Form1 の OnCreate イベントに割り当てるコードで，幅 200 ピクセル×高さ 200 ピクセルの空白のビットマップを作成し，フォームのイメージコンポーネント内に配置します。

procedure TForm1.FormCreate(Sender: TObject);
var
  Bitmap: TBitmap;	{ ビットマップを保存するための一時変数 }

begin
  Bitmap := TBitmap.Create;	{ ビットマップオブジェクトを作成 }

  Bitmap.Width := 200;	{ 幅の初期値を指定 }

  Bitmap.Height := 200;	{ 高さの初期値を指定 }

  Image.Picture.Graphic := Bitmap; { ビットマップをイメージコンポーネントに割
     り当てる }
end;


グラフィックの出力
グラフィックの出力1016041

参照	例

Delphi アプリケーションからグラフィックイメージを出力するのは簡単な作業です。必要な設定は，プリンタを呼び出すフォームの uses 節に Printers ユニットを追加するだけです。Printers ユニットは Printer と呼ばれるプリンタオブジェクトを宣言します。このオブジェクトは印刷されたページを表すキャンバスを持ちます。

グラフィックイメージを印刷するには

プリンタのキャンバスにイメージをコピーする

プリンタのキャンバスはほかのキャンバスと同じように使えます。特にこれはビットマップなどのグラフィックオブジェクトの内容をプリンタに直接コピーできることを意味します。


例1016042

次のコードはボタン PrintButton がクリックされたとき，フォームのイメージをプリンタにコピーします。

procedure TForm1.PrintButtonClick(Sender: TObject);

begin

  with Printer do

  begin

    BeginDoc;	{ 印刷開始 }

    Canvas.Draw(0, 0, Image);	{ 印刷ページの左上隅に Image を描画 }

    EndDoc;	{ 印刷終了 }

  end;

end;


参照1016043

プリンタオブジェクトの使い方

メモの内容の出力


グラフィックファイルに対する操作
グラフィックファイルに対する操作1016044

使い捨てのグラフィックイメージにはあまり価値はありません。同じ画像を毎回使ったり，作成した画像を後で使うために保存しておきたいことがよくあります。Delphi の Image コンポーネントを使うとファイルから画像をロードしたり再びファイルに保存する操作が簡単にできます。

詳細については次の各トピックを選択してください。

ファイルからの画像のロード

ファイルへの画像の保存

画像の置換


ファイルからの画像のロード
ファイルからの画像のロード1016045

参照	例

アプリケーションで画像を修正する必要がある場合，または画像をアプリケーションの外部に保存し，ユーザーや別のアプリケーションがコードを変更せずに画像を変更できるようにしたい場合，ファイルから画像をロードできることが重要になります。

グラフィックファイルを Image コンポーネントにロードするには

Image コンポーネントの Picture オブジェクトの LoadFromFile メソッドを呼び出す


参照1016046

Image コントロールの追加


例1016047

次のコードはメニュー項目［開く(O)］の OnClick イベントハンドラです。このコードは［ファイルを開く］ダイアログボックスからファイル名を取り出し，そのファイルを Image という名前の Image コンポーネントにロードします。

procedure TForm1.Open1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    CurrentFile := OpenDialog1.FileName;

    Image.Picture.LoadFromFile(CurrentFile);
  end;
end;


ファイルへの画像の保存
ファイルへの画像の保存1016048

参照	例

画像を作成または変更した後，画像を後で使うために保存したい場合があります。Delphi の Picture オブジェクトはグラフィックを複数の形式で保存でき，アプリケーション開発者は独自のグラフィックファイル形式を作成してそれらの形式も保存されるように登録できます。

Image コンポーネントの内容をファイルに保存するには

Image コンポーネントの Picture オブジェクトの SaveToFile メソッドを呼び出す

SaveToFile メソッドは保存するファイルの名前を必要とします。新しく作成する画像にファイル名が指定されていなかったり，ユーザーが既存の画像を別のファイルに保存する場合があります。どちらの場合も，アプリケーションが保存を実行する前に，コード例で示すようにユーザーからファイル名を取得する必要があります。


参照1016049

Image コントロールの追加

ファイルからの画像のロード


例1016050

次の 2 つのイベントハンドラはそれぞれメニュー項目［上書き保存(S)］と［名前を付けて保存(A)］のために記述されたもので，名前が指定済みのファイルの再保存，名前が未指定のファイルの保存，新しい名前での既存ファイルの保存を処理します。

procedure TForm1.Save1Click(Sender: TObject);
begin
  if CurrentFile <> '' then
    Image.Picture.SaveToFile(CurrentFile)
     { 名前が指定済みの場合は保存 }

  else SaveAs1Click(Sender);    { 名前が指定されていない場合は名前を取得 }
end;

procedure TForm1.Saveas1Click(Sender: TObject);
begin
  if SaveDialog1.Execute then	{ ファイル名を取得する }
  begin
    CurrentFile := SaveDialog1.FileName;{ ユーザーが指定した名前を保存 }

    Save1Click(Sender);	{ その後通常と同様に保存 }
  end;
end;


画像の置換
画像の置換1016051

参照	例

Image コンポーネントの画像はいつでも置換できます。すでにグラフィックを持っている画像に新しいグラフィックを割り当てると，新しいグラフィックが既存のものと置換されます。

Image コンポーネントの画像を置換するには

Image コンポーネントの Picture プロパティに新しいグラフィックを割り当てる

画像オブジェクトの Graphic プロパティに新しいビットマップを割り当てると，画像オブジェクトは既存のビットマップを廃棄し，新しいビットマップのオーナーシップを取得します。以前のビットマップに関連付けられていたリソースの解放は Delphi が自動的に処理します。


参照1016052

Image コントロールの追加

実行時の描画用の領域の提供

ファイルからの画像のロード

ファイルへの画像の保存


例1016053

次のコードはメニュー項目［新規作成(N)］の OnClick イベントハンドラです。このコードはダイアログボックス NewBMPForm を開きます。このダイアログボックスでユーザーは既存のビットマップ領域に使われているデフォルトサイズ以外のサイズを選択します。

procedure TForm1.New1Click(Sender: TObject);
var
  Bitmap: TBitmap;	{ 新しいビットマップのための一時変数 }

begin
  with NewBMPForm do
  begin
    ActiveControl := WidthEdit;	{ フォーカスを幅フィールドに置く }

    WidthEdit.Text := IntToStr(Image.Picture.Graphic.Width);
{ 現在のサイズを ... }

    HeightEdit.Text := IntToStr(Image.Picture.Graphic.Height);
{ ... デフォルトとして使います }

    if ShowModal <> idCancel then	{ ユーザーがダイアログボックスを取り消さな
   ければ続行 }
    begin
      Bitmap := TBitmap.Create;	{ 新しいビットマップオブジェクトを作成 }

      Bitmap.Width := StrToInt(WidthEdit.Text);
{ 指定された幅を使用 }

      Bitmap.Height := StrToInt(HeightEdit.Text);
{ 指定された高さを使用 }

      Image.Picture.Graphic := Bitmap;
{ グラフィックを新しいビットマップと置換する }

      CurrentFile := '';	{ 名前が未指定のファイルを示す }
    end;
  end;
end;


クリップボードでのグラフィックの使い方
クリップボードでのグラフィックの使い方1016054

参照	例

Windows のクリップボードを使ってアプリケーションにグラフィックをコピーしたり，貼り付けたり，ほかのアプリケーションとグラフィックを交換したりできます。Delphi のクリップボードオブジェクトを使うとグラフィックを含めた異なる種類の情報を簡単に扱えます。

アプリケーションでクリップボードオブジェクトを使う前に，クリップボードのデータへのアクセスを必要とするユニットの uses 節に ClipBrd ユニットを追加しなくてはなりません。

クリップボードへのグラフィックのコピー

クリップボードには，Image コンポーネントの内容やフォーム上のグラフィックも含めて，あらゆるグラフィックイメージをコピーできます。クリップボードにコピーした画像はすべての Windows アプリケーションで使えます。

クリップボードに画像をコピーするには

Assign メソッドを使ってクリップボードオブジェクトに画像を割り当てる

クリップボードへのグラフィックの切り取り

クリップボードへのグラフィックの切り取りはコピーとほとんど同じですが，切り取りではソースからグラフィックを消去します。

画像からグラフィックを切り取りクリップボードに入れるには

最初にクリップボードにグラフィックをコピーした後，オリジナルを消去する。オリジナルを消去するには，たとえば領域を白に設定する

クリップボードからのグラフィックの貼り付け

Windows のクリップボードにグラフィックが入っている場合，そのグラフィックを Image コンポーネントやフォームの表面などの任意のイメージオブジェクトに貼り付けできます。

クリップボードからグラフィックを貼り付けるには

1.	クリップボードの HasFormat メソッドを呼び出し，クリップボードにグラフィックが入っているか確認します。

HasFormat は論理関数です。パラメータで指定された型の項目がクリップボードに含まれている場合，True を返します。グラフィックをテストするには，CF_BITMAP を渡します。

2.	Assign メソッドを使ってクリップボード上のビットマップを貼り付け先に割り当てます。


参照1016055

クリップボードでのテキストの使い方


例1016056

例 (クリップボードへのグラフィックのコピー)

例 (クリップボードへのグラフィックの切り取り)

例 (クリップボードへのグラフィックの貼り付け)


例1016057

次のコードはメニュー項目［編集(E)｜コピー(C)］がクリックされたとき，Image という名前の Image コンポーネントからクリップボードへ画像をコピーします。

procedure TForm1.Copy1Click(Sender: TObject);
begin
  Clipboard.Assign(Image.Picture);
end;


例1016058

次のコードはメニュー項目［編集(E)｜切り取り(T)］がクリックされたとき，選択されたグラフィックをフォームから削除し，クリップボードにコピーします。

procedure TForm1.Cut1Click(Sender: TObject);
var
  ARect: TRect;

begin
  Copy1Click(Sender);	{ 画像をクリップボードにコピー }

  with Image.Canvas do
  begin
    CopyMode := cmWhiteness;	{ すべてを白としてコピー }

    ARect := Rect(0, 0, Image.Width, Image.Height);
{ ビットマップの長方形を取得 }

    CopyRect(ARect, Image.Canvas, ARect);
{ ビットマップをビットマップ自体の上にコピー }

    CopyMode := cmSrcCopy;	{ 通常のモードを復元 }
  end;
end;


例1016059

次のコードはメニュー項目［編集(E)｜貼り付け(P)］がクリックされたとき，クリップボードから Image コンポーネントに画像を貼り付けます。

procedure TForm1.Paste1Click(Sender: TObject);

var

  Bitmap: TBitmap;
begin
  if Clipboard.HasFormat(CF_BITMAP) then	{ 画像があるか確認 }

   begin

     Bitmap := TBitmap.Create;
{ クリップボードの内容を保存するためのビットマップを作成 }

     try

       Bitmap.Assign(Clipboard);
{ Assign を使ってクリップボードからビットマップを取得 }

       Image.Canvas.Draw(0, 0, Bitmap);	{ ビットマップを Image にコピー }

     finally

       Bitmap.Free;

     end;

   end;

end;


実行時のグラフィックの描画
実行時のグラフィックの描画1017001

Delphi アプリケーションでのグラフィックの描画はオブジェクトに直接ではなく，オブジェクトのキャンバスで行われます。

キャンバスはオブジェクトのプロパティであり，キャンバス自体が独自のプロパティを持つオブジェクトでもあります。キャンバスオブジェクトには 4 つの重要なプロパティがあります。

線を描画するためのペン

図形を塗りつぶすためのブラシ

テキストを書くためのフォント

イメージを表現するためのピクセル配列

キャンバスは実行時にだけ使えるため，キャンバスを使う作業はすべてコードを記述して処理します。

実行時にグラフィックを効果的に使うには，次の概念をよく理解しておいてください。

描画とペイント

ピクセル配列の使い方

線と図形の描画


描画とペイント
描画とペイント1017002

グラフィックを扱う場合，描画やペイントという用語が使われます。この 2 つの用語の相違点を理解することが重要です。

描画

描画とは線や図形などの 1 つの特定のグラフィック要素をコードを使って作成することをいいます。コード内では，キャンバスの描画メソッドを呼び出すことによって，特定のグラフィックをキャンバス上の特定の場所に描画するようオブジェクトに指示します。

ペイント

ペイントとはオブジェクト全体の外観を作成することをいいます。Windows はある時点で画面上のオブジェクトが外観を更新する必要があると判断し，OnPaint イベントを生成します。OnPaint イベントは，たとえば隠れたウィンドウが前面に出る場合などに発生します。

通常，ペイントには描画が伴います。OnPaint イベントへの応答では一般にオブジェクトは何らかのグラフィックを描画するからです。

OnPaint イベントは Windows がフォームをリペイントする必要があると判断した場合にはいつでも発生します。たとえば，フォームの上にあった別のウィンドウが閉じた場合などです。フォームの OnPaint イベントのハンドラに対して Delphi が生成するデフォルトの名前は FormPaint です。

フォームの背景をペイントしたい場合やイメージを再生成したい場合は OnPaint イベントを処理できます。


ピクセル配列の使い方
ピクセル配列の使い方1017003

参照	例

キャンバスの Pixels プロパティは画面上のイメージを構成する個々の色付きの点を表します。

特定のピクセルが何色かを調べたりピクセルの色を設定する場合以外は，Pixels に直接アクセスする必要はほとんどありません。

ピクセルはキャンバスの表面に描画されている画像であり，ペンやブラシを使うとピクセルグループを操作するのに便利です。

ピクセルの操作

キャンバスのピクセルは 2 次元の配列で，配列内の各要素は特定の色を持ちます。個々のピクセルについて読み出しまたは設定ができます。

キャンバスの左上隅が座標の原点です。

特定のピクセルの色を取り出すには

読み出したいピクセルの x 座標と y 座標をインデックスとして使い，キャンバスの Pixels プロパティを読み出す

特定のピクセルの色を設定するには

ピクセルの x 座標と y 座標をインデックスとして使い，Pixels プロパティに色値を割り当てる


参照1017004

ペンの使い方

ブラシの使い方


例1017005

例 (ピクセルの読み出し)

例 (ピクセルの設定)


例1017006

次のコードはチェックボックスがクリックされたときにチェックボックスのテキストの色をフォーム内の点 (10, 10) のピクセルの色に変更します。

procedure TForm1.CheckBox1Click(Sender: TObject);

begin

  CheckBox1.Font.Color := Canvas.Pixels[10, 10];

end;


例1017007

次のコードはボタンがクリックされたときにフォーム上の任意のピクセルを赤に変更します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Canvas.Pixels[Random(ClientWidth), Random(ClientHeight)] := clRed;

end;


ペンの使い方
ペンの使い方1017008

キャンバスの Pen プロパティは線をどのように表示するかを制御するために使います。これには図形の輪郭として描画する線も含まれます。ペンはオブジェクトのプロパティですが，ペン自体もオブジェクトの 1 つです。

直線は 2 点間に存在するピクセルグループを変更することによって描きます。

次のタスクは複数の手順からなるかプログラミングの知識が必要なものでペン特有のものです。

線と図形の描画

ペンの移動

プロパティタスク

次の表はプロパティを設定するだけで実行できるタスクの一覧です。プロパティの設定方法についての詳細は，コンポーネントプロパティの設定を参照してください。

タスク	プロパティ

ペン色の変更	Color

ペン幅の変更	Width

ペンスタイルの変更	Style

ペンモードの変更	Mode


ペンの移動
ペンの移動1017009

PenPos プロパティはペンの現在位置を格納します。ペン位置は線の描画にだけ影響します。図形とテキストに関しては，必要な座標をすべて指定します。

ペン位置を設定するには

キャンバスの MoveTo メソッドを呼び出す。キャンバスの左上隅が座標位置 (0, 0) になる

LineTo メソッドによる線の描画では現在位置が線の終点に移動します。


ブラシの使い方
ブラシの使い方1017010

キャンバスの Brush プロパティは領域の塗りつぶし方法を制御するために使います。これには図形内部の塗りつぶしも含まれます。ブラシを使って領域を塗りつぶすと多くの隣接ピクセルが指定した方法で変更されます。

次のタスクはブラシに特有です。

プロパティタスク

次の表はプロパティを設定するだけで実行できるタスクの一覧です。プロパティの設定方法についての詳細は，コンポーネントプロパティの設定を参照してください。

タスク	プロパティ

塗りつぶし色の変更	Color

ブラシスタイルの変更	Style

ビットマップをブラシの模様として使う	Bitmap


線と図形の描画
線と図形の描画1017011

参照	例

キャンバスには多くの種類の図形を描画するためのメソッドがあります。

キャンバスはペンを使って図形の輪郭を描画した後，ブラシを使ってその内部を塗りつぶします (適用する場合)。

線や図形を描画するには

そのグラフィックに関連付けられたメソッドを呼び出します。

次の表はキャンバスが描画できる図形と各図形を描画するために必要なメソッドを示しています。

描画する図形	メソッド	備考

弧	Arc	Arc メソッドは長方形に内接する楕円の周辺に沿って弧を描く

弦	Chord	Chord メソッドは長方形に内接する楕円の 2 点を結ぶ線を描く

楕円	Ellipse	Ellipse メソッドは長方形の 4 辺すべてに接する楕円を描く

線	LineTo	LineTo は現在のペン位置から指定位置までの線を描画し，線の終点を現在位置とする。キャンバスはペンを使って線を描画する

扇形	Pie

多角形	Polygon	Polygon は唯一のパラメータとして点の配列をとり，ペンを使って点を結び，最後の点と最初の点を結んで多角形を閉じる。線を描画した後，Polygon はブラシを使って多角形の内部の領域を塗りつぶす

多角線	PolyLine	PolyLine メソッドには点の配列がパラメータとして渡される。多角線の描画は最初の点に MoveTo を実行し以降の点に LineTo を実行するのと同じである

長方形	Rectangle	Rectangle メソッドは外接長方形を描画する

角の丸い長方形	RoundRect	最初の 4 つのパラメータは外接長方形で，最後の 2 つは丸い角の描き方を示す


参照1017012

描画とペイント

ペンの使い方

ブラシの使い方


例1017013

次のメソッドは，フォームが描かれた場合にフォーム上に交差する対角線を描画します。

procedure TForm1.FormPaint(Sender: TObject);

begin

  with Canvas do

  begin

    MoveTo(0, 0);

    LineTo(ClientWidth, ClientHeight);

    MoveTo(0, ClientHeight);

    LineTo(ClientWidth, 0);

  end;

end;


例1017014

例 (楕円の描画)

例 (多角形の描画)

例 (多角線の描画)

例 (長方形の描画)

例 (角の丸い長方形の描画)

例 (直線の描画)


例1017015

次のメソッドはフォームにひし形を描画します。

procedure TForm1.FormPaint(Sender: TObject);

begin

  with Canvas do

    PolyLine([Point(0, 0), Point(50, 0), Point(75, 50), Point(25, 50), Point(0, 0)]);

end;

このコードは Delphi のオープン配列パラメータの自動生成機能を利用しています。点の配列はどんなものでも渡せますが，配列をすばやく作成する簡単な方法は配列要素を [ ] で囲んで全体をパラメータとして渡す方法です。


例1017016

次のメソッドはフォームの第二象限に長方形と，それに内接する楕円を描画します。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.Rectangle(0, 0, ClientWidth div 2, ClientHeight div 2);

  Canvas.Ellipse(0, 0, ClientWidth div 2, ClientHeight div 2);

end;


例1017017

次のメソッドはフォームの第二象限に角の丸い長方形を描画します。長方形の角は，直径 10 ピクセルの円の一部であるかのように丸められます。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.RoundRect(0, 0, ClientWidth div 2, ClientHeight div 2, 10, 10);

end;


例1017018

次のコードはウィンドウの左下半分に直角三角形を描画します。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.Polygon([Point(0, 0), Point(0, ClientHeight),

    Point(ClientWidth, ClientHeight)]);

end;


Add Fields dialog box
Add Fields dialog box1018001

Use the Add Fields dialog box to create a persistent field component for a dataset:

To create a persistent field component for a dataset:

1.	Right-click the Fields editor list box.

2.	Choose Add fields from the SpeedMenu. The Add Fields dialog box appears

The Available fields list box displays all fields in the dataset which do not have persistent field components.

3.	Select the fields for which you want to create persistent field components.

4.	Click OK.

Each time you open the dataset, Delphi no longer creates dynamic field components for every column in the underlying database. It only creates persistent components for the fields you specified.

Each time you open the dataset, Delphi verifies that each non-calculated persistent field exists or can be created from data in the database. If it cannot, Delphi raises an exception warning you that the field is not valid, and does not open the dataset.

To delete a persistent field component:

1.	Select the field(s) to remove in the Fields editor list box.

2.	Press the Delete key.

Note:	Fields you remove are no longer available to the dataset and cannot be displayed by data aware controls.


Fields editor
Fields editor1018002

Use the Fields editor at design time to create persistent lists of the field components used by the datasets in your application. Persistent fields component lists are stored in your application, and do not change even if the structure of a database underlying a dataset is changed. All fields in a dataset are either persistent or dynamic.

To start the fields editor:

Double-click the dataset component.

The Fields editor appears.

Using the Fields editor

The Fields editor contains a title bar, navigator buttons, and a list box.

Title bar

The title bar displays the both the name of the data module or form containing the dataset, and the name of the dataset itself.

Navigation buttons

Use these buttons to scroll one-by-one through the records in an active dataset at design time. You can also jump to the first or last record. The buttons are dimmed if the data set is not active or empty.

List box

The List box displays the names of persistent fields components for the dataset. The first time you invoke the Fields editor for a new dataset, the list is empty because the fields components for the dataset are dynamic, not persistent. If you invoke the Fields editor for a dataset that already has persistent fields components, you see the fields component names in the list box.

To add fields to the list of persistent fields for a dataset:

1.	Right-click the list box to invoke the SpeedMenu for  the Fields editor

2.	Choose Add Fields.


Associate attributes dialog box
Associate attributes dialog box1018003

You can apply attribute sets to fields without having to recreate the settings manually if:

If several fields in datasets used by your application share common formatting properties

and

You have saved those property settings as attribute sets in the Data Dictionary.

If you change the attributes in the Data Dictionary, those changes are automatically applied to every field associated with the set the next time field components are added to the dataset.

To apply an attribute set to a field component:

1.	Double-click the dataset to invoke the Fields editor.

2.	Select the field for which to apply an attribute set.

3.	Right-click the Fields editor list box to invoke the SpeedMenu.

4.	Choose Associate attributes.

5.	Select or enter the attribute set to apply from the Attribute set name dialog box.

If there is an attribute set in the Data Dictionary that has the same name as the current field, that set name appears in the edit box.


Save attributes dialog box
Save attributes dialog box1018004

When several fields in the datasets used by your application share common formatting properties, it is more convenient to set the properties for a single field, then store those properties as an attribute set in the Data Dictionary. Attribute sets stored in the data dictionary can be easily applied to other fields.

To create an attribute set based on a field component in a dataset:

1.	Double-click the dataset to invoke the Fields editor.

2.	Select the field for which to set properties.

3.	Set the desired properties for the field in the Object Inspector.

4.	Right-click the Fields editor list box to invoke the SpeedMenu.

5.	Choose Save Attributes to save the current field痴 property settings as an attribute set in the Data Dictionary.

The name for the attribute set defaults to the name of the current field. You can specify a different name for the attribute set by choosing Save attributes as instead of Save attributes from the SpeedMenu.

Note:	You can also create attribute sets directly from the Database Explorer. When you create an attribute set from the data dictionary, the set is not applied to any fields, but you can specify two additional attributes in the set: a field type and a data-aware control that is automatically placed on a form when a field based on the attribute set is dragged onto the form. For more information, see the online help for the Database Explorer.


Retrieve attributes
Retrieve attributes1018005

To retrieve an attribute set for a field component that is different in name from the field component name, choose Retrieve attributes to specify the name of the attribute set to retrieve.


Save as attributes
Save as attributes1018006

To save an attribute set and assign it a name that differs from the currently selected field component name, choose Save as attributes, and then enter the new attribute set name.


Unassociate attributes
Unassociate attributes1018007

To remove an attribute set assignment for a selected field component, choose Unassociate attributes.


Fields Editor edit options
Fields Editor edit options1018008

Use these SpeeeMenu options to edit fields in the Field editor.

Cut

Use this option to remove selected field from the editor and place them on the Windows clipboard.

Copy

Use this option to copy selected fields to the Wincdows clipboard.

Paste

Use this option to paste the clipboard contents into an application.

Delete

Use this option to delete selected fields without copying them to the clipboard.

Select All

Use this option to select all the fields in the fields


DBGrid Columns editor
DBGrid Columns editor 1018009

The Columns editor contains a list box of defined columns, insertion and deletion buttons. Column properties are displayed in the Object Inspector.

At design time, use the DBGrid Columns editor to create a set of personal column objects for the grid. At run time, the State property for a grid with persistent column objects is automatically set to csCustomized.

Column properties determine how data is displayed in the cells of that column.  Most column properties obtain their default values from properties associated with another component, called the default source, such as a grid or an associated field component.

To create persistent columns for a grid control:

1.	Select the DBGrid component in the form.

2.	Right-click to invoke the SpeedMenu, and choose Columns editor.

Columns List box

The Columns list box displays the persistent columns that have been defined for the selected grid. When you first bring up the Columns editor, this list is empty because the grid is in its default state, containing only dynamic columns.

Add button

To create a persistent column for a grid, click on the Add button in the Columns editor.  A new column will entered the list box. Default parameters for the column will be displayed in the Object Repository.

Delete button

Use this button to delete a selected column.

Add All Fields button

To create columns for all the fields in the grid痴 dataset, click the Add All Fields button.  If the grid already contained persistent columns, a dialog box asks if you want to delete the existing columns, or append to the column set.

Delete All Columns button

Use this button to delete a persistent column from a grid.

Note:	If you delete all the columns from a grid, the grid reverts to its csDefault state and automatically builds dynamic columns for each field in the dataset.

The Column properties page

In the Columns properties displayed on the Object Inspector. The following table summarizes the properties

Property	Purpose

Alignment	Left justifies, right justifies, or centers the field data in the column. Default source:  TField.Alignment

ButtonStyle	cbsAuto:  (default) Displays a drop-down list if the associated field is a lookup field, or if the column痴 PickList property contains data.

cbsEllipsis:  Displays an ellipsis (...) button to the right of the cell.  Clicking on the button fires the grid痴 OnEditButtonClick event.

cbsNone:  The column uses only the normal edit control to edit data in the column

Color	Specifies the background color of the cells of the column.  For text foreground color, see the font property. Default Source:  TDBGrid.Color

DropDownRows 	The number of lines of text displayed by the drop-down list. Default: 7

FieldName	Specifies the field name that is associated with this column.  This can be blank.

Font	Invoke the Font editor to define the font attibutes of the column text.

PickList	Invoke the String List editor to define a list of strings to display in a drop-down list in the column. When the user chooses from the list, the corresponding field's value is set to what the user chose. PickList is similar to using a lookup field, but is more useful for lists of items that rarely change or are fixed in the application.

PopupMenu	The PopupMenu property identifies the pop-up menu associated with the control. Assign a value to PopupMenu to make a pop-up menu appear when the user selects the control and clicks the right mouse button. If the TPopupMenu痴 AutoPopup property is True, the pop-up menu appears automatically. If the menu痴 AutoPopup property is False, display the menu with a call to its Popup method

ReadOnly	True:  The data in the column cannot be edited by the user.

False: (default)  The data in the column can be edited.

Title	Click Title to expand the property list.  Define Allignment, Caption text, Color, Font and Width for the selected column.

Width	Specifies the width of the column in screen pixels. Default Source: derived from TField.DisplayWidth

Restore Defaults

You can discard all property changes in the selected column by right clicking the Restore Defaults button. The column's properties will return to their default values.


Update SQL editor
Update SQL editor1018010

Use the Update SQL editor to create SQL statements to update a dataset.

The TUpdateSQL object must be associated with a TQuery object by setting the TQuery property UpdateObject to the name of the TUpdateSQL object used to contain the SQL statements.  A datasource, and database name must be selected for the TQuery object . In addition, the SQL property must include a SQL statement defining a table.

To open the SQL editor:

1.	Select the TUpDateSQL object in the form.

2.	Right-click to invoke the SpeedMenu, and choose Update SQL editor.

The Update SQL editor has two pages, the Options page and the SQL page.

The Options page

The Options page is visible when you first invoke the editor.

Table Name

Use the Table Name combo box to select the table to update. The table names are read from the SQL statements entered in the SQL property of the TQuery object. When you specify a table name, the Key Fields and Update Fields list boxes are populated with available columns.

Key Fields

The  is used to specify the columns to use as keys during the update. Generally the columns you specify here should correspond to an existing index, especially for local Paradox and dBASE tables, but having an index is not a requirement.

Update Fields

The Update Fields list box indicates which columns should be updated. When you first specify a table, all columns in the Update Fields list box are selected for inclusion. You can multi-select fields as desired.

Get Table Fields

Read the table fields for the table name entered and list the fields.

Dataset Defaults button

Use this button to restore the default values of the associated dataset. This will cause all fields in the Key Fields list and the Update Fields list to be selected and the table name to be restored.

Select Primary Keys button

Click the Primary Key button to select key fields based on the primary index for a table.

Generate SQL button

After you specify a table, select key columns, and select update columns, click the Generate SQL button to generate the preliminary SQL statements to associate with the update component痴 ModifySQL, InsertSQL, and DeleteSQL properties.

The SQL page

Select the SQL page to view and modify the generated SQL statements.  If you have used the Generate SQL button to  generated SQL statements, then when you select this page, the statement for the ModifySQL property is already displayed in the SQL Text memo box. You can edit the statement in the box as needed.

Note:	Keep in mind that generated SQL statements are intended to be starting points for creating update statements.  You may need to modify these statements to make them execute correctly. Test each of the statements directly yourself before accepting them.

Statement Type radio buttons (Modify, Insert, and Delete)

Use these buttons to switch among auto-generated SQL statements to edit them as needed.

To accept the statements and associate them with the update component痴 SQL properties, click OK.


New Field dialog
New Field dialog box1018011

See also

Use the New Field dialog box to create new persistent fields as additions to or replacements of the other peristent fields in a dataset. There are three types of persistent fields you can create:

Data fields, which usually replace existing fields (for example to change the data type of a field), are based on columns in the table or query underlying a dataset.

Calculated fields, which displays values calculated at run time by a dataset痴 OnCalcFields event handler.

Lookup fields, which retrieve values from a specified dataset at run time based on search criteria you specify.

If the dataset is a client data set, a fourth field type is also available:

InternalCalc fields, which retrieve calculated values that are stored with the dataset (instead of being dynamically calculated in an OnCalcFields event handler).

These types of persistent fields are only for display purposes. The data they contain at run time are not retained either because they already exist elsewhere in your database, or because they are temporary. The physical structure of the table and data underlying the dataset is not changed in any way.

To create a new persistent field component:

1. Editor.

2. ist box.

3.	Choose New field from the SpeedMenu.

The New Field dialog box appears.

The New Field dialog box

The New Field dialog box contains three group boxes: Field properties, Field type, and Lookup definition.

Field properties group

The Field properties group box enables you to enter general field component information.

Name

Enter the component痴 field name. The name you enter here corresponds to the field component痴 FieldName property. Delphi uses this name to build a component name in the Component edit box. The name that appears in the Component edit box corresponds to the field component痴 Name property and is only provided for informational purposes (Name contains the identifier by which you refer to the field component in your source code). Delphi discards anything you enter directly in the Component edit box.

Type combo box

The Type combo box in the Field properties group enables you to specify the field component痴 data type. You must supply a data type for any new field component you create. For example, to display floating point currency values in a field, select Currency from the drop-down list.

Size

The Size edit box enables you to specify the maximum number of characters that can be displayed or entered in a string-based field or the size of Bytes and VarBytes fields. For all other data types, Size is meaningless.

Field type

Enables you to specify the type of new field component to create. The default type is Data. If you choose Lookup, the Dataset and Source Fields edit boxes in the Lookup definition group box are enabled.

Lookup definition

The Lookup definition group box is only used to create lookup fields. For more information, see Defining a lookup field.


Defining a data field
Defining a data field1018012

A data field replaces an existing field in a dataset. For example, for programmatic reasons you might want to replace a TSmallIntField with a TIntegerField. Because you cannot change a field痴 data type directly, you must define a new field to replace it.

Note:	Even though you define a new field to replace an existing field, the field you define must derive its data values from an existing column in a table underlying a dataset.

To create a data field in the New Field dialog box:

1.	Enter the name of an existing persistent field in the Name edit box. Do not enter a new field name.

2.	Choose a new data type for the field from the Type combo box. The data type you choose should be different from the data type of the field you are replacing.

3.	Enter the size of the field in the Size edit box, if appropriate. Size is only relevant for fields of type TStringField, TBytesField, and TVarBytesField.

4.	Select Data in the Field type radio group if it is not already selected.

5.	Choose OK. The New Field dialog box closes, the newly defined data field replaces the existing field you specified in Step 1, and the component declaration in the data module or form痴 type declaration is updated.

To edit the properties or events associated with the field component, select the component name in the Field editor list box, then edit its properties or events with the Object Inspector.


Defining a calculated field
Defining a calculated field1018013

A calculated field displays values calculated at run time by a dataset痴 OnCalcFields event handler. For example, you might create a string field that displays concatenated values from other fields.

To create a calculated field in the New Field dialog box:

1.	Enter a name for the calculated field in the Name edit box. Do not enter the name of an existing field.

2.	Choose a data type for the field from the Type combo box.

3.	Enter the size of the field in the Size edit box, if appropriate. Size is only relevant for fields of type TStringField, TBytesField, and TVarBytesField.

4.	Select Calculated in the Field type radio group.

5.	Choose OK. The newly defined calculated field is automatically added to end of the list of persistent fields in the Field editor list box, and the component declaration is automatically added to the form痴 type declaration in the source code.

6.	Place code that calculates values for the field in the OnCalcFields event handler for the dataset.

To edit the properties or events associated with the field component, select the component name in the Field editor list box, then edit its properties or events with the Object Inspector.


Programming a calculated field
Programming a calculated field1018014

After you define a calculated field, you must write code to calculate its value. Otherwise it always has a null value. Code for a calculated field is placed in the OnCalcFields event for its dataset.


Defining a lookup field
Defining a lookup field1018015

A lookup field displays values it searches for at run time based on search criteria. In its simplest form, a lookup field is passed the name of a field to search, a field value to search for, and the field in the lookup dataset whose value it should display.

For example, consider a mail-order application that enables an operator use a lookup field to determine automatically the city and state that correspond to a zip code a customer provides. In that case, the column to search on might be called ZipTable.Zip, the value to search for is the customer痴 zip code as entered in Order.CustZip, and the values to return would be those in the ZipTable.City and ZipTable.State columns for the record where ZipTable.Zip matches the current value in the Order.CustZip field.

To create a lookup field in the New Field dialog box:

1.	Enter a name for the lookup field in the Name edit box. Do not enter the name of an existing field.

2.	Choose a data type for the field from the Type combo box.

3.	Enter the size of the field in the Size edit box, if appropriate. Size is only relevant for fields of type TStringField, TBytesField, and TVarBytesField.

4.	Select Lookup in the Field type radio group. Selecting Lookup enables the Dataset and Key Fields combo boxes.

5.	Choose from the Dataset combo box drop-down list the dataset in which to look up field values. The lookup dataset must be different from the dataset for the field component itself, or a circular reference exception is raised at run time. Specifying a lookup dataset enables the Lookup Keys and Result Field combo boxes.

6.	Choose from the Key Fields drop-down list a field in the current dataset for which to match values. To match more than one field, enter field names directly instead of choosing from the drop-down list. Separate multiple field names with semicolons.

7.	Choose from the Lookup Keys drop-down list a field in the lookup dataset to match against the Source Fields field you specified in step 6. To specify more than one field, enter field names directly instead. Separate multiple field names with semicolons.

8.	Choose from the Result Field drop-down list a field in the lookup dataset to return as the value of the lookup field you are creating. To return values from more than one field in the lookup dataset, enter field names directly instead. Separate multiple field names with semicolons.


See also New Fields dialog
See Also1018016

Defining a data field

Defining a calculated field

Programming a calculated field

Defining a lookup field


Query Parameters editor
Query Parameters editor1018017

Invoke the Query Parameters editor at design time to define values for query parameters. The Query Parameters editor lists parameters that have been entered in SQL statements in the SQL property for the TQuery component. Parameters are listed in the correct order. The editor enables you to assign values to them.

To invoke the Query Parameters editor:

1.	Select the query component.

2.	Right-click the component to invoke the SpeedMenu.

3.	Choose Define Parameters.

Using the Query Parameters editor

Parameters defined in the SQL property are displayed. For queries without previously defined parameters, the Parameter name list box is empty.

Data type combo box

The Data type combo box lists the data type for a parameter selected in the list box. If you add a parameter to the SQL property, you must set its data type.

Value edit box

The Value edit box enables you to enter a value for a selected parameter, and the Null Value check box enables you set a Null value for the selected parameter if its data type permits Null values.

Note:	Defining parameters at design time also prepares the query for execution. A query with parameters must be prepared before it can be executed at run time. To signal the end of parameter definition, choose OK.


StoredProc Parameters editor
StoredProc Parameters editor1018018

Many stored procedures require you to pass them a series of input arguments, or parameters, to specify what and how to process. The order in which you specify input parameters is significant, and is determined by the stored procedure definition on the server.

At design time, the easiest and safest way to enter input parameters is to invoke the StoredProc Parameters editor. The StoreProc Parameters editor lists input parameters in the correct order, and lets you assign values to them.

To invoke the StoredProc Parameters editor:

1.	Select the stored procedure component.

2.	Right-click the component to invoke the SpeedMenu.

3.	Choose Define Parameters.

The StoredProc Parameters editor

Parameter name list box

The Parameter name list box displays all input, output, and result parameters for the procedure. Information on input and output parameters is retrieved from the server. For some servers (such as Sybase), parameter information may not be accessible. In this case, the Parameter name list box is empty, and you must add the names and order of input and output parameters in order to use the procedure.

Parameter type combo box

The Parameter type combo box describes whether a parameter selected in the list box is an input, output, or results parameter. If a server痴 stored procedure allows it, a single parameter may be both an input and output. If you add a parameter to the list, you must set the parameter type for it.

Data type combo box

The Data type combo box lists the data type for a parameter selected in the list box. If you add a parameter to the list, you must set its data type.

Value edit box

The Value edit box enables you to enter a value for a selected input parameter, and the Null Value check box enables you set a Null value for the selected input parameter if its data type supports Null values.

Add button

The Add button enables you to add parameters to a stored procedure definition when your server does not pass the information to Delphi.

Delete button

Enables you to remove parameters you have added,.

Clear button

Removes all parameters from the list. Do not add, delete, or clear parameters for servers that pass parameter information to Delphi except if you are working with Oracle overloaded stored procedures.

Note:	Defining parameters at design time also prepares the stored procedure for execution. A stored procedure must be prepared before it can be executed at run time. To signal the end of parameter definition, choose OK.


Field Link designer
Field Link designer1018019

At design time, drop a TDataSource object on the form and define a datasource. Select the TTable component and double-click the MasterFields property in the Object Inspector to invoke the Field Link designer.

The Field Link Designer provides a visual way to link (join) master and detail tables.

Available Indexes combo box

The Available Indexes combo box displays the currently selected index used to join the tables. Unless you specify a different index name in the table痴 IndexName property, the default index used for the link is the primary index for the table. Other available indexes defined on the table can be selected from the drop-down list.

To link master and detail tables:

1.	Select the field to use to link the detail table in the Detail Fields list

2.	Select the field to link the master table in the Master Fields list.

3.	Choose Add.

The selected fields are be displayed in the Joined Fields list box. For example,

OrderNo -> OrderNo

Note:	For tables on a database server, the Available Indexes combo box will not appear, and you must manually select the detail and master fields to join in the Detail Fields and Master Fields list boxes.


ListView Columns Editor
ListView Columns Editor1018020

Use the ListView Columns editor at design time to control the number of columns and their headings in a listview component.

When the ViewStyle property of a {TListView} component is set to vsReport, and ShowColumnHeaders is set to True, the headings specified with the ListView Columns editor are visible at run time.

To invoke the ListView Columns editor:

Select the TListView object and double-click the Columns property value in the Object Inspector.

Using the ListView Columns editor

The ListView Columns editor contains a Columns list box, Add and Delete buttons, and Move Up/Down buttons to move your cursor.

Column properties are displayed in the Object Inspector when the column is selected.  The column properties are Caption, Alignment, and Width.

Columns list box

The Columns list box displays the names of existing column headings. For new components this list is always empty.

To add a column, click Add. A default entry is made in the list box.  Select the entry and edit column's properties in the Object Inspector.

To delete a column, select the column and click Delete.

Column properties displayed in the Object Inspector.

Caption

Specify the heading for a new or existing column in this box. When you press return,  the name, appears in the Columns list box.

Alignment

Choose the alignment for a column. Choices are Left Justify, Center, and Right Justify. Note that the first column heading is always left justified; you cannot change the alignment for this column.

Width

Specifies the width of the column.


ListView Items Editor
ListView Items Editor1018021

Use the ListView Items editor at design time to add or delete the items displayed in a listview component. You can add or delete new items and sub-items, and you can set the caption, image index, and state index for each item in the ListView Items editor.

To invoke the ListView Items editor:

Select the TListView object and double-click the Items property value in the Object Inspector.

Using the ListView Items editor

The ListView Items editor contains an Items group box with an Items list box, a New Item button, a New SubItem button, and a Delete button. When you first add a listview control to a form, the Items list box is empty and the New SubItem and Delete buttons are disabled.  When you enter or change item properties for a selected item, the Apply button is enabled so that you can activate changes immediately.

The ListView Items editor also contains an Item Properties group box for setting the properties of the listview item currently selected in the Items list box. The Item Properties group box contains a Caption edit box, an Image Index edit box, and a State Index edit box.

Items group box

Create and delete listview items and subitems in the Items group box. To create a new item, click New Item. A default item caption appears in the Items list box. Specify an item's properties, including its caption,  in the Items Properties group box. When you create a new item, or select an existing item, the New SubItem button is enabled so that you can nest items within other items in the listview. If the Items list box contains items, the Delete button is also enabled. To delete an item, select it in the Items list box and click Delete.

Item Properties group box

Set the properties for a selected item in the Item Properties group box. Enter a name for the item in the Caption edit box. As you enter the name, it changes in the Items list box.

To display an image to the left of an item that  is not currently selected, specify the index number of the image in the Image Index edit box. To suppress image display, set Image Index to -1 (the default).

To display an image to the left of an item that is currently selected, specify the index number of the image in the State Index edit box. The index number represents an index into the StateImages property of the listview component. To suppress image display, set State Index to -1 (the default).


TreeView Items Editor
TreeView Items Editor1018022

Use the TreeView Items editor at design time to add items to a treeview component, delete items from a treeview component, or load images from disk into a treeview component. You can specify the text associated with individual treeview items, and set the image index, selected index, and state index for items.

To invoke the TreeView Items editor:

Select the TTreeView object and double-click the Items property value in the Object Inspector.

Using the TreeView Items editor

The TreeView Items editor contains an Items group box with an Items list box, a New Item button, a New SubItem button, a Delete button, and a Load button. When you first add a treeview control to a form, the Items list box is empty, and the New SubItem and Delete buttons are disabled. When you enter or change item properties for a selected item the Apply button is enabled so that you can activate changes immediately.

The TreeView Items editor also contains an Item Properties group box for setting the properties of the treeview item currently selected in the Items list box. The Item Properties group box contains a Text edit box, and Image Index edit box, a Selected Index edit box, and a State Index edit box.

Items group box

Create, load,  and delete treeview items and subitems in the Items group box. To load a set of existing treeview items from disk, click Load. To create a new item, click New Item. Default text for the item appears in the Items list box. Specify an item's properties, including its text,  in the Items Properties group box.

When you create a new item, or select an existing item, the New SubItem button is enabled so that you can nest items within other items in the treeview. If the Items list box contains items, the Delete button is also enabled. To delete an item, select it in the Items list box and click Delete.

Item Properties group box

Set the properties for a selected item in the Item Properties group box. Enter text  for the item in the Caption edit box. As you enter the name, it changes in the Items list box.

To display an image to the left of an item that  is not currently selected, specify the index number of the image in the Image Index edit box. To suppress image display, set Image Index to -1 (the default).

To display an image to left of a selected item, specify the index number of the image in the Selected Index edit box. The index is zero-based. To suppress image display, set Selected Index to -1 (the default).

To display an additional image to the left of an item , specify the index number of the image in the State Index edit box. The index number represents an index into the StateImages property of the listview component. The index is zero-based. To suppress image display, set State Index to -1 (the default).


HeaderControl Sections Editor
HeaderControl Sections Editor1018023

Use the HeaderControl Sections editor at design time to divide a header control into sections and to assign properties to those sections. A section is a resizeable, moveable header within a header control.

To invoke the HeaderControl Sections editor:

Select the THeaderControl object and double-click the Sections property value in the Object Inspector.

Using the HeaderControl Sections editor

The Sections group box contains a Sections list box that displays the names of individual sections within a header control, a Add button for creating a new section, and a Delete button for deleting sections.

Section properties are displayed in the Object Inspector.

Sections group box

Create and delete sections for a header control in the Sections group box. To create a section, click Add. A numbered section header, named "Untitled," appears in the Sections list box, and the Delete button is enabled. Default properties for Width, Min, Max, Style, Alignment, and Allow click appear in the Object Inspector.

To delete a section, select it in the Sections list box and click Delete.

Section properties

Allignment

Specify the alignment for the text or image displayed in the section at run time. By default, Alignment is set to Left Justify.

AllowClick

To prevent users from clicking a section, uncheck the Allow click check box. Allow click is checked by default, enabling users to click a section.

MaxWidth

Specify the maximum width. The default value for Max is 10000.

MinWIdth

Specify the minimum width. The proposed default value for Min is 0.

Style

Specify the drawing style for the section. By default, Style is set to Text, meaning that text only is displayed in the section. To display an image in the header, set Style to OwnerDraw and write the code to draw an object in the header at run time.

Text

Defines the header title. Enter the title and press return.

Width

Width box, specify a default width (in pixels) for the section. The proposed default value for Width is 50.


StatusBar Panels Editor
StatusBar Panels Editor1018024

Use the StatusBar Panels editor at design time to divide a status bar control into panels and to assign properties to those panels. A panel is a fixed width section within a status bar.

To invoke the StatusBar Panels editor:

Select the TStatusBar object and double-click the Panels property value in the Object Inspector.

Using the StatusBar Panels editor

The Panels editor contains a Panels list box that displays the names of individual panels within a status bar control, an Add button for creating a new panel, and a Delete button for deleting panels.

Panel properties are displayed in the Object Inspector.

Panels group box

Create and delete panels for a status bar control in the Panels group box. To create a panel, click Add. A numbered panel , named "Untitled," appears in the Panels list box, and the Delete button is enabled. Default properties for Width, Style, Bevel, and Alignment appear in the Object Inspector.

To delete a panel, select it in the Panel list box and click Delete.

Panel properties

Set the properties for a selected panel in the Object Inspector..

Alignment

Specify the alignment for the text or image displayed in the panel at run. By default, Alignment is set to Left Justify.

Bevel

Specify the bevel type for the panel. By default, Bevel is set to Lowered.

Style

Specify the drawing style for the panel. By default, Style is set to Text, meaning that text only is displayed in the panel. To display an image in the panel, set Style to OwnerDraw and write the code to draw an object in the panel at run time.

Text

Enter the text to display in the panel within the status bar control.

Width

Specify a default width (in pixels) for the panel. The default value for Width is 50.


Add page dialog box
Add page dialog box1018025

Specify the name for a new page to add to the Object Repository in the Add page edit box. After you add a page to the Object Repository, it appears as a separate tab sheet when you choose File|New to invoke the New Items dialog box for the Object Inspector.


Rename page dialog box
Rename page dialog box1018026

Specify a new name for a an existing page in the Object Repository in the Rename page edit box. After you rename a page to the Object Repository, it appears in place of the old name on the existing page.


Instantiating forms at run time
Instantiating forms at run time1019001

Example

If you move a form into the Available Forms List Box in the Forms page of the Project Options dialog box, you must instantiate that form at run time. You do not instantiate any forms that are in the Auto-Create Forms List Box, as Delphi creates these forms automatically at run time.

Instantiate a form a run time when you cannot determine at design time how many instances of the form will be required when the application is running. For example, if you write an MDI application that allows the user to open any number of MDI child windows, you should instantiate each child form at run time. Instantiating forms at run time can also reduce the memory requirements of the application and reduce the amount of startup time when the application is run.

Note:	When creating an application that instantiates forms at run time, make sure that the code of the application does not try to access the instance of the form before it has been created.

To instantiate a form at run time,

1.	Add the name of the unit where the form is declared to the uses clause of the unit that will instantiate the form. This is necessary only if the form type is declared in a different unit.

2.	Declare a memory variable of the type of the form.

3.	Assign the return value of the Create constructor of the form type to the memory variable.

The memory variable specifies the instance of the form type.

Note:	The name of the memory variable identifier that the instance of the form is assigned to should not be the name of an existing object or component. While unique instance names are not required at run time, they are recommended so that the instance of the form is not confused with the Name of another object.


Example1019002

The following example declares a memory variable called SpecForm1 of type TSpecForm.  Then, an instance of TSpecForm is created and assigned to SpecForm1. Finally, SpecForm1 is displayed with the Show method.

Note:	The unit in which TSpecForm is declared (SpecUnit) should be added to the uses clause of the unit that contains this code.

uses ..., SpecUnit;       { Add the unit name to the uses clause }

:

var

  SpecForm1: TSpecForm;   { Declare the form instance variable }

:

SpecForm1 := TSpecForm.Create(Self);  { Create the form instance }

SpecForm1.Show;                        { Show SpecForm1 }


System (brief)
System (brief)1020001

These system keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Action or command

F7	Records a keyboard macro

F8	Plays back a keyboard macro

F9	Run|Run

F10	Accesses the menu bar

F11	View|Object Inspector

F12	View|Toggle Form/Unit

Alt+F2	Add watch at cursor

Alt+F7	Run to cursor

Alt+F9	Displays a SpeedMenu

Alt+F10	Project|Compile

Ctrl+F1	Topic search

Ctrl+F2	Run|Program Reset

Ctrl+F3	View|Call Stack

Ctrl+F7	Evaluate/modify

Ctrl+F8	Toggle breakpoint

Ctrl+F9	Project|Compile

Ctrl+F11	Run|Step over

Ctrl+Hyphen	File|Close

Ctrl+F12	View|Units

Shift+ F12	View|Forms

Alt+B	View|Window list

Alt+E	File|Open(Note: opens Open dialog box, even when Code Editor window does not have focus)

Alt+H	Displays context-sensitive Help

Alt+N	Displays the next page

Alt+O	File|Save As(Note: opens Save As dialog box, even when Code Editor window does not have focus)

Alt+-	Displays the previous page

Alt+W	File|Save

Alt+X	File|Exit

Alt+Z	Accesses the File menu


Clipboard control (brief)
Clipboard control (brief)1020002

These Clipboard keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Command

Ins	Edit|Paste

Plus (+)	Edit|Copy

Minus (-)	Edit|Cut


Editor (brief)
Editor (brief)1020003

See also

These editor keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Action or command

F5	Search|Find (forward from cursor position)

F6	Search|Replace (forward from cursor position)

Alt+F2	Control|Maximize

Alt+F5	Search|Find (backward from cursor position)

Alt+F6	Search|Replace (backward from cursor position)

Alt+F9	Displays the local menu

Shift+F4	Tiles windows horizontally

Shift+F5	Search|Search Again

Shift+F6	Repeats the last Search|Replace operation

Esc	Cancels a command at a prompt or enters an escape character at the cursor

Del	Deletes a character or block at the cursor

Star	Edit|Undo

Backspace	Deletes the character to the left of the cursor

Shift+Backspace	Deletes the character to the left of the cursor

Tab	Inserts a tab character

Enter	Inserts a new line with a carriage return

Ctrl+B	Moves to the bottom of the window

Ctrl+C	Centers line in window

Ctrl+D	Moves down one screen

Ctrl+E	Moves up one screen

Ctrl+K	Deletes to the beginning of a line

Ctrl+M	Inserts a new line with a carriage return

Ctrl+S	Performs an incremental search

Ctrl+T	Moves to the top of the window

Ctrl+U	Edit|Redo

Ctrl+Backspace	Deletes the word to the left of the cursor

Ctrl+Enter	Inserts an empty new line

Ctrl+- (dash)	Closes the current page

Alt+A	Marks a non-inclusive block

Alt+B	Displays a list of open files

Alt+C	Mark the beginning of a column block

Alt+D	Deletes a  line

Alt+G	Search|Go to line number

Alt+I	Toggles insert mode

Alt+K	Deletes of the end of a line

Alt+L	Marks a line

Alt+M	Marks an inclusive block

Alt+N	Displays the contents of the next page

Alt+P	Prints the selected block

Alt+Q	Causes next character to be interpreted as an ASCII sequence

Alt+R	Reads a block from a file

Alt+S	Search|Find

Alt+T	Search|Replace

Alt+U	Edit|Undo

Alt+Backspace	Deletes the word to the right of the cursor

Alt+Hyphen	Displays the contents of the previous file buffer

Ctrl+Q+[	Finds the matching delimiter (forward)

Ctrl+Q+Ctrl+[	Finds the matching delimiter (forward)

Ctrl+Q+]	Finds the matching delimiter (backward)

Ctrl+Q+Ctrl+]	Finds the matching delimiter (backward)

Ctrl+O+A  	Open file at cursor

Ctrl+O+B  	Browse symbol at cursor

Ctrl+O+O  	Toggles the case of a selection

Ctrl+F1	Help keyword search

Ctrl+F5	Toggles case-sensitive searching

Ctrl+F6	Toggles regular expression searching


See also1020004

Block commands

Bookmark operations

Cursor movement


Block commands (brief)
Block commands (brief)1020005

See also

These block command keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Action

Alt+A	Marks a non-inclusive block

Alt+C	Marks a column as a block

Alt+L	Marks a line as a block

Alt+M	Marks an inclusive block

Alt+P	Prints the contents of a block

Alt+R	Reads a block from a file


See also1020006

Bookmark operations

Cursor movement

Editor


Bookmark operations (brief)
Bookmark operations (brief)1020007

See also

These bookmark operations keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Action

Alt+0	Sets bookmark 0

Alt+1	Sets bookmark 1

Alt+2	Sets bookmark 2

Alt+3	Sets bookmark 3

Alt+4	Sets bookmark 4

Alt+5	Sets bookmark 5

Alt+6	Sets bookmark 6

Alt+7	Sets bookmark 7

Alt+8	Sets bookmark 8

Alt+9	Sets bookmark 9

Alt+J+0	Goes to bookmark 0

Alt+J+1	Goes to bookmark 1

Alt+J+2	Goes to bookmark 2

Alt+J+3	Goes to bookmark 3

Alt+J+4	Goes to bookmark 4

Alt+J+5	Goes to bookmark 5

Alt+J+6	Goes to bookmark 6

Alt+J+7	Goes to bookmark 7

Alt+J+8	Goes to bookmark 8

Alt+J+9	Goes to bookmark 9


See also1020008

Block commands

Cursor movement

Editor


Cursor movement (brief)
Cursor movement (brief)1020009

See also

These cursor movement keyboard shortcuts apply to the Brief keystroke mapping scheme.

Shortcut	Action

UpArrow	Moves up one line in the same column position

DownArrow	Moves down one line in the same column position

Home	Moves to the start of a line

End	Moves to the end of a line

Left Arrow	Moves one character to the left

Right Arrow	Moves one character to the right

PgDn	Moves down one screen in the current window

PgUp	Moves up one screen in the current window

Ctrl+Left Arrow	Moves one word to the left

Ctrl+Right Arrow	Moves one word to the right

Ctrl+PgDn	Moves to the end of a file

Ctrl+PgUp	Moves to the beginning of a file

Shift+Tab	Moves backward one tab stop

Shift+Home	Moves to the first column in a window

Shift+End	Moves to the last column in a window

Ctrl+Home	Moves to the top of a screen in the same column position

Ctrl+End	Moves to the bottom of a screen in the same column position

Ctrl+B	Moves to the bottom of the window

Ctrl+C	Moves to the center of the window

Ctrl+D	Scrolls down one screen

Ctrl+E	Scrolls down one screen


See also1020010

Block commands

Bookmark operations

Editor


System (classic)
System (classic)1021001

These system keyboard shortcuts apply to the Classic keystroke mapping scheme.

Shortcut	Action or command

F1	Displays context-sensitive Help

F2	File|Save

F3	File|Open

F4	Run to Cursor

F5	Control|Maximize

F6	Displays the next page

F7	Run|Trace Into

F8	Run|Step Over

F9	Run|Run

F11	View|Object Inspector

F12	View|Toggle Form/Unit

Alt+F3	File|Close

Alt+F10	Displays a SpeedMenu

Alt+X 	File|Exit

Alt+0 	View|Window LIst

Ctrl+F1	Topic Search

Ctrl+F2	Run|Program Reset

Ctrl+F3	View|Call Stack

Ctrl+F4	Evaluate/Modify

Ctrl+F7	Add Watch at Cursor

Ctrl+F8	Toggle Breakpoint

Ctrl+F9	Project|Compile

Ctrl+F12	View|Units

Shift+F12	View|Forms

Ctrl+Shift+P	Plays back a keyboard macro

Ctrl+Shift+R	Records a keyboard macro

Ctrl+Shift+S	Performs an incremental search

Ctrl+K+D	Accesses the menu bar

Ctrl+K+S	File|Save


Clipboard control (classic)
Clipboard control (classic)1021002

These Clipboard control keyboard shortcuts apply to the Classic keystroke mapping scheme.

Shortcut	Command

Ctrl+Ins	Edit|Copy

Shift+Del	Edit|Cut

Shift+Ins	Edit|Paste


Editor (classic)
Editor (classic)1021003

See also

These editor keyboard shortcuts apply to the Classic keystroke mapping scheme.

Shortcut	Action or command

F1	Topic Search

Ctrl+F1	Topic Search

F6	Displays the next page

Shift+F6	Displays the previous page

Ctrl+A	Moves one word left

Ctrl+C	Scrolls down one screen

Ctrl+D	Moves the cursor right one column, accounting for the autoindent setting

Ctrl+E	Moves the cursor up one line

Ctrl+F	Moves one word right

Ctrl+G	Deletes the character to the right of the cursor

Ctrl+H	Deletes the character to the left of the cursor

Ctrl+I	Inserts a tab

Ctrl+L	Search|Search Again

Ctrl+N	Inserts a new line

Ctrl+P	Causes next character to be interpreted as an ASCII sequence

Ctrl+R	Moves up one screen

Ctrl+S	Moves the cursor left one column, accounting for the autoindent setting

Ctrl+T	Deletes a word

Ctrl+V	Turns insert mode on/off

Ctrl+W	Moves down one screen

Ctrl+X	Moves the cursor down one line

Ctrl+Y	Deletes a line

Ctrl+Z	Moves the cursor up one line

Ctrl+Shift+S	Performs an incremental search

End 	Moves to the end of a line

Home	Moves to the start of a line

Enter	Inserts a carriage return

Ins 	Turns insert mode on/off

Del 	Deletes the character to the right of the cursor

Backspace	Deletes the character to the left of the cursor

Tab 	Inserts a tab

Space	Inserts a blank space

Left Arrow	Moves the cursor left one column, accounting for the autoindent setting

Right Arrow	Moves the cursor right one column, accounting for the autoindent setting

Up Arrow	Moves up one line

Down Arrow	Moves down one line

Page Up	Moves up one page

Page Down	Moves down one page

Ctrl+Left Arrow	Moves one word left

Ctrl+Right Arrow	Moves one word right

Ctrl+Home	Moves to the top of a screen

Ctrl+End 	Moves to the end of a screen

Ctrl+PgDn	Moves to the bottom of a file

Ctrl+PgUp	Moves to the top of a file

Ctrl+Backspace	Move one word to the right

Ctrl+Del 	Deletes a currently selected block

Ctrl+Space	Inserts a blank space

Ctrl+Enter	Opens file at cursor

Ctrl+Tab	Moves to the next page

Shift+Tab 	Deletes the character to the left of the cursor

Shift+Backspace	Deletes the character to the left of the cursor

Shift+Left Arrow	Selects the character to the left of the cursor

Shift+Right Arrow	Selects the character to the right of the cursor

Shift+Up Arrow	Moves the cursor up one line and selects from the left of the starting cursor position

Shift+Down Arrow	Moves the cursor down one line and selects from the right of the starting cursor position

Shift+PgUp	Moves the cursor up one screen and selects from the left of the starting cursor position

Shift+PgDn	Moves the cursor down one line and selects from the right of the starting cursor position

Shift+End 	Selects from the cursor position to the end of the current line

Shift+Home	Selects from the cursor position to the start of the current line

Shift+Space	Inserts a blank space

Shift+Enter	Inserts a new line with a carriage return

Shift+Ctrl+Tab	Moves to the previous page

Ctrl+Shift+Left Arrow	Selects the word to the left of the cursor

Ctrl+Shift+Right Arrow	Selects the word to the right of the cursor

Ctrl+Shift+Home	Selects from the cursor position to the start of the current file

Ctrl+Shift+End 	Selects from the cursor position to the end of the current file

Ctrl+Shift+PgDn	Selects from the cursor position to the bottom of the screen

Ctrl+Shift+PgUp	Selects from the cursor position to the top of the screen

Ctrl+Shift+Tab	Moves to the previous page

Alt+Backspace	Edit|Undo

Alt+Shift+Backspace	Edit|Redo

Alt+Shift+Left Arrow	Selects the column to the left of the cursor

Alt+Shift+Right Arrow	Selects the column to the right of the cursor

Alt+Shift+Up Arrow	Moves the cursor up one line and selects the column from the left of the starting cursor position

Alt+Shift+Down Arrow	Moves the cursor down one line and selects the column from the left of the starting cursor position

Alt+Shift+Page Up	Moves the cursor up one screen and selects the column from the left of the starting cursor position

Alt+Shift+Page Down	Moves the cursor down one line and selects the column from the right of the starting cursor position

Alt+Shift+End	Selects the column from the cursor position to the end of the current line

Alt+Shift+Home	Selects the column from the cursor position to the start of the current line

Ctrl+Alt+Shift+Left Arrow	Selects the column to the left of the cursor

Ctrl+Alt+Shift+Rght Arrow	Selects the column to the right of the cursor

Ctrl+Alt+Shift+Home	Selects the column from the cursor position to the start of the current file

Ctrl+Alt+Shift+End	Selects the column from the cursor position to the end of the current file

Ctrl+Alt+Shift+Page Up	Selects the column from the cursor position to the bottom of the screen

Ctrl+Alt+Shift+Page Down	Selects the column from the cursor position to the top of the screen


See also1021004

Block commands

Bookmark operations

Cursor movement

Miscellaneous commands


System (default)
System (default)1022001

These system keyboard shortcuts apply to the Default keystroke mapping scheme.

Shortcut	Action or command

F1	Displays context-sensitive Help

F4	Run|Go to Cursor

F5	Run|Toggle Breakpoint

F7	Run|Trace Into

F8	Run|Step Over

F9	Run|Run

F11	View|Object Inspector

F12	View|Toggle Form/Unit

Alt+F10	Displays a SpeedMenu

Alt+0	View|Window List

Ctrl+F1	Help|Topic Search

Ctrl+F2	Run|Program Reset

Ctrl+F3	View|Call Stack

Ctrl+F4	Closes current file

Ctrl+F5	Add Watch at Cursor

Ctrl+F7	Evaluate/Modify

Ctrl+F9	Project|Compile

Ctrl+F12	View|Units

Shift+F12	View|Forms

Ctrl+Shift+P	Plays back a key macro

Ctrl+Shift+R	Records a key macro

Ctrl+K+D	Accesses the menu bar

Ctrl+K+S	File|Save


Clipboard control (default)
Clipboard control (default)1022002

These Clipboard keyboard shortcuts apply to the Default keystroke mapping scheme.

Shortcut	Command

Ctrl+Ins	Edit|Copy

Shift+Del	Edit|Cut

Shift+Ins	Edit|Paste

Ctrl+C	Edit|Copy

Ctrl+V	Edit|Paste

Ctrl+X	Edit|Cut


Editor (default)
Editor (default)1022003

See also

These editor keyboard shortcuts apply to the Default keystroke mapping scheme.

Shortcut	Action or command

F1	Help|Topic Search

Ctrl+F1	Help|Topic Search

F3	Search|Search Again

Ctrl+E	Search|Incremental Search

Ctrl+F	Search|Find

Ctrl+I	Inserts a tab character

Ctrl+j	Templates pop-up menu

Ctrl+N	Inserts a new line

Ctrl+P	Causes next character to be interpreted as an ASCII sequence

Ctrl+R 	Search|Replace

Ctrl+S	File|Save

Ctrl+T	Deletes a word

Ctrl+Y	Deletes a line

Ctrl+Z	Edit|UndoCtrl+<space bar>Code Completion pop-up window

Ctrl+Shift+g	Inserts a new Globally Unique Identifier (GUID)

Ctrl+Shift+I	Indents block

Ctrl+Shift+U	Outdents block

Ctrl+Shift+Y	Deletes to the end of a line

Ctrl+Shift+Z	Edit|Redo

Ctrl+Shift+<space bar>	Code Parameters pop-up window

Alt+[	Finds the matching delimiter (forward)

Alt+]	Finds the matching delimiter (backward)

End 	Moves to the end of a line

Home	Moves to the start of a line

Enter	Inserts a carriage return

Ins 	Turns insert mode on/off

Del 	Deletes the character to the right of the cursor

Backspace	Deletes the character to the left of the cursor

Tab 	Inserts a tab

Space	Inserts a blank space

Left Arrow	Moves the cursor left one column, accounting for the autoindent setting

Right Arrow	Moves the cursor right one column, accounting for the autoindent setting

Up Arrow	Moves up one line

Down Arrow	Moves down one line

Page Up	Moves up one page

Page Down	Moves down one page

Ctrl+Left Arrow	Moves one word left

Ctrl+Right Arrow	Moves one word right

Ctrl+Tab 	Moves to the next page

Ctrl+Shift+Tab	Moves to the previous page

Ctrl+Backspace	Deletes the word to the right of the cursor

Ctrl+Home	Moves to the top of a file

Ctrl+End 	Moves to the end of a file

Ctrl+Del 	Deletes a currently selected block

Ctrl+Space	Inserts a blank space

Ctrl+PgDn	Moves to the bottom of a screen

Ctrl+PgUp	Moves to the top of a screen

Ctrl+Up Arrow	Scrolls up one line

Ctrl+Down Arrow	Scrolls down one line

Ctrl+Enter	Opens file at cursor

Shift+Tab 	Moves the cursor to the left one tab position

Shift+Backspace	Deletes the character to the left of the cursor

Shift+Left Arrow	Selects the character to the left of the cursor

Shift+Right Arrow	Selects the character to the right of the cursor

Shift+Up Arrow	Moves the cursor up one line and selects from the left of the starting cursor position

Shift+Down Arrow	Moves the cursor down one line and selects from the right of the starting cursor position

Shift+PgUp	Moves the cursor up one screen and selects from the left of the starting cursor position

Shift+PgDn	Moves the cursor down one line and selects from the right of the starting cursor position

Shift+End 	Selects from the cursor position to the end of the current line

Shift+Home	Selects from the cursor position to the start of the current line

Shift+Space	Inserts a blank space

Shift+Enter	Inserts a new line with a carriage return

Ctrl+Shift+Left Arrow	Selects the word to the left of the cursor

Ctrl+Shift+Right Arrow	Selects the word to the right of the cursor

Ctrl+Shift+Home	Selects from the cursor position to the start of the current file

Ctrl+Shift+End 	Selects from the cursor position to the end of the current file

Ctrl+Shift+PgDn	Selects from the cursor position to the bottom of the screen

Ctrl+Shift+PgUp	Selects from the cursor position to the top of the screen

Ctrl+Shift+Tab	Moves to the previous page

Alt+Backspace	Edit|Undo

Alt+Shift+Backspace	Edit|Redo

Alt+Shift+Left Arrow	Selects the column to the left of the cursor

Alt+Shift+Right Arrow	Selects the column to the right of the cursor

Alt+Shift+Up Arrow	Moves the cursor up one line and selects the column from the left of the starting cursor position

Alt+Shift+Down Arrow	Moves the cursor down one line and selects the column from the left of the starting cursor position

Alt+Shift+Page Up	Moves the cursor up one screen and selects the column from the left of the starting cursor position

Alt+Shift+Page Down	Moves the cursor down one line and selects the column from the right of the starting cursor position

Alt+Shift+End	Selects the column from the cursor position to the end of the current line

Alt+Shift+Home	Selects the column from the cursor position to the start of the current line

Ctrl+Alt+Shift+Left Arrow	Selects the column to the left of the cursor

Ctrl+Alt+Shift+Rght Arrow	Selects the column to the right of the cursor

Ctrl+Alt+Shift+Home	Selects the column from the cursor position to the start of the current file

Ctrl+Alt+Shift+End	Selects the column from the cursor position to the end of the current file

Ctrl+Alt+Shift+Page Up	Selects the column from the cursor position to the bottom of the screen

Ctrl+Alt+Shift+Page Down	Selects the column from the cursor position to the top of the screen


See also1022004

Block commands

Bookmark operations

Cursor movement

Miscellaneous commands


System (Epsilon)
System (Epsilon)1023001

These system keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action or command

F1	Displays context-sensitive Help

F5	Toggle Breakpoint

F8	Run|Step Over

F9	Run|Run

F10	Edit|Redo

F11	View|Object Inspector

F12	View|Toggle Form/Unit

Alt+F9	Project|Compile

Alt+F10	Displays a SpeedMenu

Alt+0	View|Window List

Ctrl+F2	Run|Program Reset

Ctrl+F5	Run|Add Watch

Ctrl+F6	Displays the next page

Ctrl+Shift+F6	Displays the previous page

Ctrl+F7	File|Save As

Ctrl+F9	Project|Compile

Ctrl+F12	View|Units

Shift+F12	View|Forms

Ctrl+X+(	Records a keyboard macro

Ctrl+X+)	Ends a keyboard macro recording

Ctrl+X+e	Plays back the the last keyboard macro recorded

Ctrl+X+E	Plays back the the last keyboard macro recorded

Ctrl+X+b	Displays a list of open files

Ctrl+X+B	Displays a list of open files

Ctrl+X+s	File|Save As

Ctrl+X+S	File|Save As

Ctrl+X+Ctrl+F	File|Open

Ctrl+X+Ctrl+S	File|Save

Ctrl+X+Ctrl+W	File|Save


Clipboard control (Epsilon)
Clipboard control (Epsilon)1023002

These Clipboard keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action or command

Ctrl+Y	Edit|Paste

Alt+w	Edit|Copy

Esc+@w	Edit|Copy

Ctrl+Alt+w	Edit|Copy (appends to current contents)

Esc+Ctrl+w	Edit|Copy (appends to current contents)


Editor (Epsilon)
Editor (Epsilon)1023003

See also

These editor keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action or command

Ctrl+H	Deletes the character to the left of the current cursor position

Backspace	Deletes the character to the left of the current cursor position

Alt+Del	Deletes all text in the block between the cursor and the previous matching delimiter (cursor must be on ')', '}' or ']')

Esc+Del	Deletes all text in the block between the cursor and the previous matching delimiter (cursor must be on ')', '}' or ']')

Ctrl+Alt+H	Deletes the word to the left of the current cursor position

Alt+Backspace	Deletes the word to the left of the current cursor position

Esc+BackSpace	Deletes the word to the left of the current cursor position

Esc+Ctrl+H	Deletes the word to the left of the current cursor position

Ctrl+D	Deletes the currently selected character or character to the right of the cursor

Del	Deletes the currently selected character or character to the right of the cursor

Alt+\	Deletes spaces and tabs around the cursor on the same line

Esc+\	Deletes spaces and tabs around the cursor on the same line

Ctrl+Alt+K	Deletes all text in the block between the cursor and the next matching delimiter (cursor must be on ')', '}' or ']')

Esc+Ctrl+K	Deletes all text in the block between the cursor and the next matching delimiter (cursor must be on ')', '}' or ']')

Ctrl+X+0	Deletes the contents of the current window

Alt+d	Deletes to word to the right of the cursor

Esc+@d	Deletes to word to the right of the cursor

Ctrl+K	Cuts the contents of line and places it in the Clipboard

Ctrl+Alt+B	Locates the next matching delimiter (cursor must be on ')', '}' or ']')

Esc+Ctrl+B	Locates the next matching delimiter (cursor must be on ')', '}' or ']')

Alt+)	Locates the next matching delimiter (cursor must be on ')', '}' or ']')

Esc+)	Locates the next matching delimiter (cursor must be on ')', '}' or ']')

Alt+Shift+O	Locates the next matching delimiter (cursor must be on ')', '}' or ']')

Ctrl+Alt+F	Locates the previous matching delimiter (cursor must be on ')', '}' or ']')

Esc+Ctrl+F	Locates the previous matching delimiter (cursor must be on ')', '}' or ']')

Alt+c	Capitalizes the current word

Esc+@c	Capitalizes the current word

Ctrl+L	Centers the active window

Ctrl+M	Inserts a carriage return

Ctrl+X+i	Inserts the contents of a file at the cursor

Ctrl+X+I	Inserts the contents of a file at the cursor

Ctrl+O	Inserts a new line after the cursor

Alt+x	Invokes the specified command or macro

Esc+@x	Invokes the specified command or macro

F2	Invokes the specified command or macro

Ctrl+X+Ctrl+X	Exchanges the locations of the cursor position and a bookmark

Ctrl+Shift+-	Displays context-sensitive Help

Alt+Shift+/	Displays context-sensitive Help

Alt+?	Displays context-sensitive Help

Esc+?	Displays context-sensitive Help

Ctrl+_	Displays context-sensitive Help

Ctrl+X+,	Browses the symbol at the cursor

Tab	Inserts a tab

Alt+Tab	Indents to the current line to the text on the previous line

Esc+Tab	Indents to the current line to the text on the previous line

Alt+l	Converts the current word to lowercase

Esc+@l	Converts the current word to lowercase

Ctrl+X+m	Project|Compile

Ctrl+X+M	Project|Compile

Esc+End	Displays the next window in the buffer list

Ctrl+X+n	Displays the next window in the buffer list

Ctrl+X+N	Displays the next window in the buffer list

Esc+Home	Displays the previous window in the buffer list

Ctrl+X+p	Displays the previous window in the buffer list

Ctrl+X+P	Displays the previous window in the buffer list

Ctrl+X+Ctrl+E	Invoke a command processor

Ctrl+Q	Interpret next character as an ASCII code

Ctrl+X+r	Edit|Redo

Ctrl+X+R	Edit|Redo

F10	Edit|Redo

Ctrl+F10	Edit|Redo

Ctrl+X+Ctrl+R	Edit|Redo

Ctrl+X+u	Edit|Undo

Ctrl+X+U	Edit|Undo

F9	Edit|Undo

Ctrl+F9	Edit|Undo

Ctrl+X+Ctrl+U	Edit|Undo

Ctrl+S	Incrementally searches for a string entered from the keyboard

Ctrl+R	Incrementally searches backward through the current file

Ctrl+Alt+S	Search|Find (using regular expressions)

Esc+Ctrl+S	Search|Find (using regular expressions)

Ctrl+Alt+R	Search|Find (using regular expressions; backward from cursor)

Esc+Ctrl+R	Search|Find (using regular expressions; backward from cursor)

Alt+Shift+5	Search|Replace

Alt+Shift+7	Search|Replace

Alt+&	Search|Replace

Esc+&	Search|Replace

Alt+%	Search|Replace

Esc+%	Search|Replace

Alt+*	Search|Replace (using regular expressions)

Esc+*	Search|Replace (using regular expressions)

Ctrl+X+Ctrl+N	Search|Find Error

Ctrl+X+g	Search|Go To Line Number

Ctrl+X+G	Search|Go To Line Number

Crl+T	Transposes the two characters on either side of the cursor

Ctrl+X+Ctrl+T	Transposes the two lines on either side of the cursor

Alt+t	Transposes the two words on either side of the cursor

Esc+t	Transposes the two words on either side of the cursor

Esc+T	Transposes the two words on either side of the cursor

Alt+U	Converts a word to all uppercase

Esc+U	Converts a word to all uppercase

Esc+@u	Converts a word to all uppercase

Ins	Toggles insert mode on/off


See also1023004

Block commands

Bookmark operations

Cursor movement


Block commands (Epsilon)
Block commands (Epsilon)1023005

See also

These block command keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action

Ctrl+Alt+\	Indents a block

Esc+Ctrl+\	Indents a block

Ctrl+X+Ctrl+I	Indents a block

Ctrl+X+Tab	Indents a block

Ctrl+W	Cuts a block and places its contents in the Clipboard

Ctrl+X+w	Writes a block to a file

Ctrl+X+W	Writes a block to a file


See also1023006

Bookmark operations

Cursor movement

Editor


Bookmark operations (Epsilon)
Bookmark operations (Epsilon)1023007

See also

These bookmark operations keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action

Ctrl+@	Sets a bookmark at the current cursor position

Alt+@	Sets a bookmark at the current cursor position

Esc+@@	Sets a bookmark at the current cursor position

Ctrl+2	Sets a bookmark at the current cursor position

Alt+2	Sets a bookmark at the current cursor position

Ctrl+X+.	Goes to the specified bookmark


See also1023008

Block commands

Cursor movement

Editor


Cursor movement (Epsilon)
Cursor movement (Epsilon)1023009

See also

These cursor movement keyboard shortcuts apply to the Epsilon keystroke mapping scheme.

Shortcut	Action

Ctrl+B	Moves to the left one character

Left Arrow	Moves to the left one character

Ctrl+F	Moves to the right one character

RightArrow	Moves to the right one character

Alt+m	Moves the cursor to the end of the indentation

Esc+m	Moves the cursor to the end of the indentation

Esc+M	Moves the cursor to the end of the indentation

Alt+b	Moves the cursor to the left one word

Esc+@b	Moves the cursor to the left one word

Ctrl+LeftArrow	Moves the cursor to the left one word

Alt+f	Moves to the cursor to the right one word

Esc+@f	Moves to the cursor to the right one word

Ctrl+RgAr	Moves to the cursor to the right one word

Ctrl+A	Moves to the beginning of the current line

Esc+LeftArrow	Moves to the beginning of the current line

Ctrl+E	Moves to the end of the current line

Esc+RightArrow	Moves to the end of the current line

Alt-,	Moves to the top of the current window

Esc+,	Moves to the top of the current window

Home	Moves to the top of the current window

Alt-.	Moves to the bottom of the current window

Esc+.	Moves to the bottom of the current window

End	Moves to the bottom of the current window

Ctrl+P	Moves the cursor up a line

UpAr	Moves the cursor up a line

Ctrl+N	Moves the cursor down a line

DnAr	Moves the cursor down a line

Alt+Shift-,	Goes to the start of the file

Alt+<	Goes to the start of the file

Esc+<	Goes to the start of the file

Ctrl+Home	Goes to the start of the file

Alt+Shift-.	Goes to the end of the file

Alt+>	Goes to the end of the file

Esc+>	Goes to the end of the file

Ctrl+End	Goes to the end of the file

Ctrl+V	Moves down one page in the current file

PgDn	Moves down one page in the current file

Ctrl+F6	Moves down one page in the current file

Shift+Ctrl+F6	Moves up one page in the current file

Alt+v	Moves up one page in the current file

Esc+@v	Moves up one page in the current file

PgUp	Moves up one page in the current file

Alt+Z	Scrolls the contents of the active window down a line

Esc+Z	Scrolls the contents of the active window down a line

Ctrl+Z	Scrolls the contents of the active window up a line


See also1023010

Block commands

Bookmark operations

Editor


About keyboard shortcuts
About keyboard shortcuts1024001

See also

Keyboard shortcuts are two- or three-keystroke combinations you can press, while in the Code Editor, to perform a command or access a dialog box. The function of specific keyboard shortcuts depends on which keystroke mapping scheme you select.

Code Editor available keyboard mapping schemes are:

Default	Key bindings that match the CUA standard

Classic	Key bindings that match the Delphi programming environment

Brief	Key bindings that emulate most of the standard Brief keystrokes

Epsilon	Key bindings that emulate a a large part of the Epsilon editor

To select a keymapping:

1.	On the Editor display page of the Environment Options dialog box.

2.	Select a keyboard mapping scheme from the list of available schemes.

3.	Click OK.

To use SpeedSettings to set your keymappings:

1.	On the Editor options page of the Environment Options dialog box.

2.	Select a keyboard mapping scheme from the Editor SpeedSettings options.

3.	Click OK.

Note:	Using the Keystroke Mapping list box or the Editor SpeedSettings to change the mapping of your keystrokes can create conflicts with standard Windows keyboard commands.

For example, the Brief keystroke mapping defines Alt+E as File|Open, while the standard Windows action for Alt+E is to activate the Edit menu. The mapped key takes precedence so that Alt+E allows you to open a file.


See also1024002

IDE keyboard shortcuts

Keyboard shortcuts by function

Working with the Code editor


Default keystroke mapping1024003

The Default keystroke mapping scheme provides key bindings that match the CUA standard. For detailed information, choose one of the  topics below for a list of keyboard shortcuts:

Clipboard control

Debugger

Editor

Block commands

Bookmark operations

Cursor movement

Miscellaneous commands

System


Classic keystroke mapping1024004

The Classic keystroke mapping scheme provides key bindings that match the Delphi programming enviroment. For detailed information, choose one of the  topics below for a list of keyboard shortcuts:

Clipboard control

Debugger

Editor

Block commands

Bookmark operations

Cursor movement

Miscellaneous commands

System


Brief keystroke mapping1024005

The Brief keystroke mapping scheme provides key bindings that emulate the Brief editor. For detailed information, choose one of the  topics below for a list of keyboard shortcuts:

Clipboard control

Debugger

Editor

Block commands

Bookmark operations

Cursor movement

System


Epsilon keystroke mapping1024006

The Epsilon keystroke mapping scheme provides key bindings that emulate most of the Epsilon editor. For detailed information, choose one of the  topics below for a list of keyboard shortcuts:

Clipboard control

Debugger

Editor

Block commands

Bookmark operations

Cursor movement

System


Debugger (default, classic, brief and Epsilon)
Debugger (default, classic, brief and Epsilon)1024007

The Debugger keyboard shortcuts apply to all keystroke mapping schemes:

Default

Classic

Brief

Epsilon

Breakpoint view

Ctrl+E 	Edit Breakpoint

Ctrl+V	View Source

Ctrl+S	Edit Source

Ctrl+D	Delete Breakpoint

Ctrl+A 	Add Breakpoint

Call stack view

Ctrl+V	View Source

Ctrl+E 	Edit Source

Watch view

Ctrl+E	Edit Watch

Ctrl+A 	Add Watch

Ctrl+D	Delete Watch


Block commands (default and classic)
Block commands (default and classic)1024008

See also

These block command shortcuts apply to the Default and the Classic keystroke mappings schemes.

Shortcut	Action or command

Ctrl+K+B	Marks the beginning of a block

Ctrl+K+C	Copies a selected block

Ctrl+K+H	Hides/shows a selected block

Ctrl+K+I	Indents a block by the amount specified in the Block Indent combo box on the Editor options page of the Environment Options dialog box

Ctrl+K+K	Marks the end of a block

Ctrl+K+L	Marks the current line as a block

Ctrl+K+N	Changes a block to uppercase

Ctrl+K+O	Changes a block to lowercase

Ctrl+K+R	Reads a block from a file

Ctrl+K+T	Marks a word as a block

Ctrl+K+U	Outdents a block by the amount specified in the Block Indent combo box on the Editor options page of the Environment Options dialog box.

Ctrl+K+V	Moves a selected block

Ctrl+K+W	Writes a selected block to a file

Ctrl+K+Y	Deletes a selected block

Ctrl+O+C	Marks a column block

Ctrl+O+I	Marks an inclusive block

Ctrl+O+K	Marks a non-inclusive block

Ctrl+O+L	Marks a line as a block

Ctrl+Q+B	Moves to the beginning of a block

Ctrl+Q+K	Moves to the end of a block


See also1024009

Bookmark operations

Cusor movement

Editor (classic)

Editor (default)

Miscellaneous commands


Bookmark operations (default and classic)
Bookmark operations (default and classic)1024010

See also

The following bookmark operations shortcuts apply to the Default and the Classic keystroke mapping schemes.

Shortcut	Action

Ctrl+K+0 	Sets bookmark 0

Ctrl+K+1 	Sets bookmark 1

Ctrl+K+2 	Sets bookmark 2

Ctrl+K+3 	Sets bookmark 3

Ctrl+K+4 	Sets bookmark 4

Ctrl+K+5 	Sets bookmark 5

Ctrl+K+6 	Sets bookmark 6

Ctrl+K+7 	Sets bookmark 7

Ctrl+K+8 	Sets bookmark 8

Ctrl+K+9 	Sets bookmark 9

Ctrl+K+Ctrl+0	Sets bookmark 0

Ctrl+K+Ctrl+1	Sets bookmark 1

Ctrl+K+Ctrl+2	Sets bookmark 2

Ctrl+K+Ctrl+3	Sets bookmark 3

Ctrl+K+Ctrl+4	Sets bookmark 4

Ctrl+K+Ctrl+5	Sets bookmark 5

Ctrl+K+Ctrl+6	Sets bookmark 6

Ctrl+K+Ctrl+7	Sets bookmark 7

Ctrl+K+Ctrl+8	Sets bookmark 8

Ctrl+K+Ctrl+9	Sets bookmark 9

Ctrl+Q+0 	Goes to bookmark 0

Ctrl+Q+1 	Goes to bookmark 1

Ctrl+Q+2 	Goes to bookmark 2

Ctrl+Q+3 	Goes to bookmark 3

Ctrl+Q+4 	Goes to bookmark 4

Ctrl+Q+5 	Goes to bookmark 5

Ctrl+Q+6 	Goes to bookmark 6

Ctrl+Q+7 	Goes to bookmark 7

Ctrl+Q+8 	Goes to bookmark 8

Ctrl+Q+9 	Goes to bookmark 9

Ctrl+Q+Ctrl+0	Goes to bookmark 0

Ctrl+Q+Ctrl+1	Goes to bookmark 1

Ctrl+Q+Ctrl+2	Goes to bookmark 2

Ctrl+Q+Ctrl+3	Goes to bookmark 3

Ctrl+Q+Ctrl+4	Goes to bookmark 4

Ctrl+Q+Ctrl+5	Goes to bookmark 5

Ctrl+Q+Ctrl+6	Goes to bookmark 6

Ctrl+Q+Ctrl+7	Goes to bookmark 7

Ctrl+Q+Ctrl+8	Goes to bookmark 8

Ctrl+Q+Ctrl+9	Goes to bookmark 9

These shortcuts apply only to the Default scheme:

Shortcut	Action

Shift+Ctrl+0	Sets bookmark 0

Shift+Ctrl+1	Sets bookmark 1

Shift+Ctrl+2	Sets bookmark 2

Shift+Ctrl+3	Sets bookmark 3

Shift+Ctrl+4	Sets bookmark 4

Shift+Ctrl+5	Sets bookmark 5

Shift+Ctrl+6	Sets bookmark 6

Shift+Ctrl+7	Sets bookmark 7

Shift+Ctrl+8	Sets bookmark 8

Shift+Ctrl+9	Sets bookmark 9

Ctrl+0	Goes to bookmark 0

Ctrl+1	Goes to bookmark 1

Ctrl+2	Goes to bookmark 2

Ctrl+3	Goes to bookmark 3

Ctrl+4	Goes to bookmark 4

Ctrl+5	Goes to bookmark 5

Ctrl+6	Goes to bookmark 6

Ctrl+7	Goes to bookmark 7

Ctrl+8	Goes to bookmark 8

Ctrl+9	Goes to bookmark 9


See also1024011

Block commands

Cursor movement

Editor (classic)

Editor (default)

Miscellaneous commands


Cursor movement (default and classic)
Cursor movement (default and classic)1024012

See also

These cursor movement shortcuts apply to the Default and the Classic keystroke mapping schemes.

Shortcut	Action

Ctrl+Q+B	Moves to the beginning of a block

Ctrl+Q+C	Moves to end of a file

Ctrl+Q+D	Moves to the end of a line

Ctrl+Q+E	Moves to the top of the window

Ctrl+Q+K	Moves to the end of a block

Ctrl+Q+P	Moves to previous position

Ctrl+Q+R	Moves to the beginning of a file

Ctrl+Q+S	Moves to the beginning of a line

Ctrl+Q+T	Moves to the top of the window

Ctrl+Q+U	Moves to the bottom of the window

Ctrl+Q+X	Moves to the bottom of the window


See also1024013

Block commands

Bookmark operations

Editor (classic)

Editor (default)

Miscellaneous commands


Miscellaneous commands (default and classic)
Miscellaneous commands (default and classic)1024014

See also

These miscellaneous commands shortcuts apply to the Default and the Classic keystroke mapping schemes.

Shortcut	Action or command

Ctrl+K+D	Accesses the menu bar

Ctrl+K+E	Changes a word to lowercase

Ctrl+K+F	Changes a word to uppercase

Ctrl+K+S	File|Save

Ctrl+Q+A	Search|Replace

Ctrl+Q+F	Search|Find

Ctrl+Q+Y	Deletes to the end of a line

Ctrl+Q+[ 	Finds the matching delimiter (forward)

Ctrl+Q+Ctrl+[	Finds the matching delimiter (forward)

Ctrl+Q+] 	Finds the matching delimiter (backward)

Ctrl+Q+Ctrl+]	Finds the matching delimiter (backward)

Ctrl+O+A  	Open file at cursor

Ctrl+O+B  	Browse symbol at cursor

Ctrl+O+G  	Search|Go to line number

Ctrl+O+O  	Inserts compiler options and directives

Ctrl+O+U	Toggles case


See also 1024015

Block commands

Bookmark operations

Cursor movement

Editor (classic)

Editor (default)


Keyboard shortcuts by function
Keyboard shortcuts by function1024016

See also

Chose one of these topics for shortcuts for some common menu commands. The shortcuts are different for each keystroke mapping scheme.

Build commands

Debug commands

Edit commands

File commands

Search commands


See also1024017

Keyboard shortcuts

Working with the Code editor


Keyboard shortcuts for the File menu
Keyboard shortcuts for the File menu1024018

See also

The table below lists keyboard shortcuts for file commands.

Command	Shortcut	Mapping

File|Open	F3	Classic

Alt+E 	Brief

Ctrl+X+Ctrl+F	Epsilon

Open File At Cursor	Ctrl+O+A	Default, Classic, Brief

File|Save	Ctrl+K+S	Default, Classic

Ctrl+S	Default

F2	Classic

Alt+W	Brief

Ctrl+X+Ctrl+S	Epsilon

Ctrl+X+Ctrl+W	Epsilon

File|Save As	Alt+O 	Brief

Ctrl+F7	Epsilon

Ctrl+X+s	Epsilon

Ctrl+X+S	Epsilon

File|Close	Alt+F3	Classic

Ctrl+Hyphen	Brief

Control|Close	Alt+F4	Default, Classic, Brief, Epsilon

File|Exit	Alt+X	Classic, Brief

File menu	Alt+Z	Brief

For more information about Delphi's keystroke mapping schemes, choose one of the following topics:

Default keystroke mapping

Classic keystroke mapping

Brief keystroke mapping

Epsilon keystroke mapping


See also1024019

Build commands

Debug commands

Edit commands

Keyboard shortcuts

Search commands


Keyboard shortcuts for the Edit menu
Keyboard shortcuts for the Edit menu1024020

See also

The table below lists the keyboard shortcuts for commands on the Edit menu.

Command	Shortcut	Mapping

Edit|Cut	Shift+Del	Default, Classic

Ctrl+X	Default

Minus (-)	Brief

Edit|Copy	Ctrl+Ins	Default, Classic

Ctrl+C	Default

Plus (+)	Brief

Alt+w	Epsilon

Esc+@w	Epsilon

Ctrl+Alt+w	Epsilon

Esc+Ctrl+w	Epsilon

Edit|Paste	Shift+Ins	Default, Classic

Ctrl+V	Default

Ins	Brief

Ctrl+Y	Epsilon

Edit|Redo	Ctrl+Shift+Z	Default

Alt+Shift+Backspace	Default, Classic

Ctrl+U	Brief

Ctrl+X+r	Epsilon

Ctrl+X+R	Epsilon

F10	Epsilon

Ctrl+F10	Epsilon

Ctrl+X+Ctrl+R	Epsilon

Edit|Undo	Alt+Backspace	Default, Classic

Star	Brief

Alt+U	Brief

Ctrl+X+u	Epsilon

Ctrl+X+U	Epsilon

F9	Epsilon

Ctrl+F9	Epsilon

Ctrl+X+Ctrl+U	Epsilon

For more information about Delphi's keystroke mapping schemes, choose one of the following topics:

Default Keystroke Mapping

Classic Keystroke Mapping

Brief Keystroke Mapping

Epsilon Keystroke Mapping


See also1024021

Build commands

Debug commands

File commands

Keyboard shortcuts

Search commands


Search commands keyboard shortcuts
Search commands keyboard shortcuts1024022

See also

The table below lists the keyboard shortcuts for commands on the Search menu.

Command	Shortcut	Mapping

Find	Ctrl+Q+F	Default, Classic

Ctrl+F	Default

F5	Brief

Alt+F5	Brief

Alt+S	Brief

Ctrl+Alt+S	Epsilon

Esc+Ctrl+S	Epsilon

Ctrl+Alt+R	Epsilon

Esc+Ctrl+R	Epsilon

Replace	Ctrl+Q+A	Default, Classic

Ctrl+R 	Default

Alt+T	Brief

F6	Brief

Alt+F6	Brief

Alt+&	Epsilon

Esc+&	Epsilon

Alt+%	Epsilon

Esc+%	Epsilon

Alt+*	Epsilon

Esc+*	Epsilon

Search Again	F3	Default

Ctrl+L	Classic

Shift+F5	Brief

Go To Line Number	Ctrl+O+G	Default, Classic, Brief

Alt+G	Brief

Ctrl+X+g	Epsilon

Ctrl+X+G	Epsilon

For more information about Delphi's keystroke mapping schemes, choose one of the following topics:

Default Keystroke Mapping

Classic Keystroke Mapping

Brief Keystroke Mapping

Epsilon Keystroke Mapping


See also1024023

Build commands

Debug commands

Edit commands

File commands

Keyboard shortcuts


Debug commands keyboard shortcuts
Debug commands keyboard shortcuts1024024

See also

The table below lists the keyboard shortcuts for debug operations.

Command	Shortcut	Mapping

Run|Go to Cursor	F4	Default, Classic

Run|Toggle Breakpoint	F5	Default

Run|Trace Into	F7	Default, Classic

Run|Step Over	F8	Default, Classic, Epsilon

Run|Program Reset	Ctrl+F2	Default, Classic, Brief, Epsilon

Run|Add Watch	Ctrl+F5	Epsilon

Add Watch at Cursor	Ctrl+F5	Default

Ctrl+F7	Classic

Alt+F2	Brief

Browse Symbol at Cursor	Ctrl+O+B	Default, Classic, Brief

Evaluate/Modify	Ctrl+F7	Default, Brief

Ctrl+F4	Classic

Toggle Breakpoint	Ctrl+F8	Classic, Brief

F5	Epsilon

Run to Cursor	F4	Classic

Run to Cursor	Alt+F7	Brief

For more information about Delphi's keystroke mapping schemes, choose one of the following topics:

Default Keystroke Mapping

Classic Keystroke Mapping

Brief Keystroke Mapping

Epsilon Keystroke Mapping


See also1024025

Build commands

Edit commands

File commands

Keyboard shortcuts

Search commands


Build commands keyboard shortcuts
Build commands keyboard shortcuts1024026

See also

This table lists the keyboard shortcuts for build operations:

Command	Shortcut	Mapping

Project|Compile	Ctrl+F9	Default, Classic, Brief

Alt+F9	Default, Classic, Epsilon

Alt+F10	Brief

Ctrl+X+m	Epsilon

Ctrl+X+M	Epsilon

Run|Run	F9	Default, Classic, Brief, Epsilon

For more information about Delphi's keystroke mapping schemes, choose one of the following topics:

Default Keystroke Mapping

Classic Keystroke Mapping

Brief Keystroke Mapping

Epsilon Keystroke Mapping


See also1024027

Debug commands

Edit commands

File commands

Keyboard shortcuts

Search commands


Delphi IDE でのキーボードサポート
Delphi IDE でのキーボードサポート1025001

参照

Delphi の IDE キーボードショートカットは 2 つまたは 3 つのキーの組み合わせです。このキーボードショートカットを押すと，メニューを開かずに直接コマンドを実行したりダイアログボックスにアクセスしたりできます。コードエディタウィンドウで使うショートカットについては，キーボードショートカットを参照してください。

ほかのウィンドウで使うショートカットについては，次の各トピックを参照してください。

フォームのキーボードショートカット

プロジェクトマネージャのキーボードショートカット

オブジェクトインスペクタのキーボードショートカット

オブジェクトブラウザのキーボードショートカット


参照1025002

機能別のキーボードショートカット

コードエディタの操作


フォームのキーボードショートカット
フォームのキーボードショートカット1025003

参照

フォームで使うキーボードショートカットを次に示します。

IDE ではキーボードを使って，フォーム上でコンポーネントの移動やサイズ変更ができます。次の表に選択，移動，サイズ変更のためのキー入力を示します。移動したりサイズ変更するには，まずコンポーネントを選択しなくてはなりません。

キーボードコマンド	説明

〔Tab〕	コンポーネントを選択する (Z オーダー)

〔Shift〕+〔Tab〕	前のコンポーネントを選択する (Z オーダー)

矢印キー	矢印キーの方向のもっとも近いコンポーネントを選択する

〔Ctrl〕+矢印キー	選択したコンポーネントを一度に 1 ピクセルだけ移動する

〔Shift〕+矢印キー	選択したコンポーネントのサイズを一度に 1 ピクセルだけ変更する

〔Ctrl〕+〔Shift〕+矢印キー	選択したコンポーネントを一度に 1 グリッドだけ移動する (［グリッドに合わせる(G)］が有効な場合)

〔Del〕	選択したコンポーネントを削除する

〔Esc〕	フォーム，グループボックスなどのコンテナグループを選択する

〔F11〕	オブジェクトインスペクタと直前にアクティブだったフォーム (またはユニット) との間で制御を切り替える

〔F12〕	フォームとその関連するユニットを切り替える

〔Ctrl〕+〔F12〕	［ユニットの表示］ダイアログボックスを表示する

〔Shift〕+〔F12〕	［フォームの表示］ダイアログボックスを表示する

〔Alt〕+〔F12〕	フォームのテキスト表示とビジュアル表示とを切り替える

キーボードを使ってコンポーネントをフォームに追加するには

1.	〔Alt〕+〔V〕+〔L〕を押して［コンポーネント］ダイアログボックスを表示します。

2.	フォームに追加するコンポーネントの名前の先頭文字を入力するか，〔Tab〕を押します。矢印キーでリストをスクロールして選択します。

3.	〔Alt〕+〔A〕または〔Enter〕を押して，コンポーネントをフォームに追加します。〔Esc〕を押すと，［コンポーネント］ダイアログボックスが閉じます。

コンポーネントリスト内を移動するためのキー

〔Home〕	リスト内の最初のコンポーネントを表示する

〔End〕	リスト内の最後のコンポーネントを表示する

キーボードを使ってコンポーネントのプロパティを変更するには

1.	変更するコンポーネントを〔Tab〕または矢印キーで選択します。

2.	〔Enter〕を押してオブジェクトインスペクタに切り替えます。

3.	変更するプロパティを矢印キーで選択します。

4.	プロパティの新しい値を入力して〔Enter〕を押します。

5.	フォームに戻るには，〔Alt〕+〔V〕+〔F〕を押してからリストでフォームを選択します。


参照1025004

キーボードショートカット


プロジェクトマネージャのキーボードショートカット
プロジェクトマネージャのキーボードショートカット1025005

プロジェクトマネージャで使うキーボードショートカットを次に示します。

キーボードコマンド	説明

矢印キー	フォームとユニットを選択する

〔Enter〕	選択したユニットを表示する

〔Shift〕+〔Enter〕	選択したフォームを表示する

〔Ins〕	ファイルをプロジェクトに追加する

〔Del〕	プロジェクトからファイルを削除する


オブジェクトインスペクタのキーボードショートカット
オブジェクトインスペクタのキーボードショートカット1025006

オブジェクトインスペクタで使うキーボードショートカットを次に示します。

キーボードコマンド	説明

↑と↓	プロパティまたはハンドラを選択する

←と→	値列またはインデント列の値を編集する

〔Tab〕	オブジェクトインスペクタでプロパティ列と値列を切り替える

〔Tab〕+<英字>	指定した英字で始まる最初のプロパティに直接ジャンプする

〔Ctrl〕+〔Tab〕	オブジェクトインスペクタでプロパティタブとイベントタブを切り替える

〔Page Up〕	プロパティを 1 画面上に移動する

〔Page Down〕	プロパティを 1 画面下に移動する

〔Alt〕+F10〕	スピードメニューの表示

〔Alt〕+↓

〔Ctrl〕+↓

〔Ctrl〕+〔Enter〕

キーボードを使ってコンポーネントのプロパティを変更するには

1.	変更するコンポーネントを〔Tab〕または矢印キーで選択します。

2.	〔Enter〕を押してオブジェクトインスペクタに切り替えます。

3.	変更するプロパティを矢印キーで選択します。

4.	プロパティの新しい値を入力して〔Enter〕を押します。

5.	フォームに戻るには，〔Alt〕+〔V〕+〔F〕を押してからリストでフォームを選択します。


コンポーネントメニュー
コンポーネントメニュー1026001

コンポーネントメニューには次のコマンドがあります。

コンポーネントの新規作成(N)	コンポーネントエキスパートを開きます。

コンポーネントのインストール(I)	コンポーネントを既存のパッケージまたは新規パッケージにインストールします。

ActiveX コントロールの取り込み(X)	ActiveX コントロールのタイプライブラリを Delphi プロジェクトに追加します。

コンポーネントテンプレートの作成(T)	コンポーネントをカスタマイズし，新しい名前，パレットページ，アイコンとともにテンプレートとして保存します。

パッケージのインストール(P)	プロジェクトで必要なパッケージを指定します。

パレットの設定(C)	［環境オプション］ダイアログボックスを開きます。


コンポーネント(C)｜コンポーネントの新規作成(T)
コンポーネント(C)｜コンポーネントの新規作成(N)1026002

参照

［コンポーネントの新規作成］ダイアログボックスは新しいコンポーネントの基本ユニットを作成するために使います。

［上位クラス(A)］	ドロップダウンリストを使って新しいコンポーネントの基本クラスを選択するか，新しいコンポーネントの基本クラス名を入力します。コンポーネント宣言の中でオーバーライドした場合を除いて，新しいコンポーネントは上位クラスからすべてのプロパティ，メソッド，イベントを継承します。基本クラスを入力したら，デフォルトのエントリが［クラス名(C)］と［ユニットファイル名(F)］に書き込まれます。これらのエントリはそのまま使うことも，編集することもできます。

［クラス名(C)］	作成する新しいクラスの名前です。一般的な規則として，Object Pascal クラスには名前の前に T を付けます。たとえば，新しいボタンコンポーネントの名前は TMYBUTTON などとします。

［パレットページ名(P)］	新しいコンポーネントを表示するコンポーネントパレットのページをドロップダウンリストから選択するか，そのページの名前を入力します。

［ユニットファイル名(F)］	新しいコンポーネントが入るユニットの名前です。ユニット名にはディレクトリパスを指定できます。ディレクトリパスを指定しない場合，ユニットはカレントディレクトリに作成されます。ユニットディレクトリが［検索パス(S)］に表示されていない場合，そのディレクトリはパスの最後に追加されます。

［検索パス(S)］	ファイルの検索で使われるパスです。

［インストール(I)］	コンポーネントを新規パッケージまたは既存のパッケージにインストールします。パッケージを特定したら，［パッケージ］ダイアログボックスが表示されます。パッケージエディタから［コンポーネントの新規作成］ダイアログボックスを開いた場合，このボタンは表示されません。

［ユニットの作成(C)］	コンポーネントコードをコードエディタに表示します。ユニットは，明示的に追加しない限り，現在のプロジェクトには追加されません。パッケージエディタから［コンポーネントの新規作成］ダイアログボックスを開いた場合，このボタンは表示されません。


コンポーネント(C)｜コンポーネントのインストール(I)
コンポーネント(C)｜コンポーネントのインストール(I)1026003

参照

［コンポーネント(C)｜コンポーネントのインストール(I)］を選択して，コンポーネントを既存のパッケージまたは新規パッケージにインストールします。

必要な情報を入力したら，［OK］を押します。［パッケージ］ダイアログボックスが表示されます。

既存のパッケージへのインストール

この場合，ユニット名で指定されるコンポーネントコードを既存のパッケージファイルに記述します。

新規パッケージへのインストール

この場合，新規パッケージを宣言し，ユニット名で指定されるコンポーネントコードをそのパッケージに記述します。


新規パッケージへのインストール
新規パッケージへのインストール1026004

［ユニットファイル名(U)］	インストールするユニットの名前を入力します。ユニットが［検索パス(S)］に表示されている場合，フルパス名の入力は不要です。ユニットディレクトリが［検索パス(S)］に表示されていない場合，そのディレクトリはパスの最後に追加されます。

［検索パス(S)］	ファイルの検索で使われるパスです。

［パッケージファイル名(P)］	作成するパッケージの名前を入力します。パッケージ名にはディレクトリパスを指定できます。ディレクトリパスを指定しない場合，パッケージはカレントディレクトリに作成されます。ファイルやディレクトリの選択ダイアログボックスを開くには，［参照(R)］をクリックします。［パッケージ］ダイアログボックスにファイル名を直接入力すると，拡張子として .DPK が自動的に追加されます。

パッケージ名はプロジェクト内でユニークでなければなりません。パッケージに「STATS」という名前を付けた場合，パッケージエディタはそのパッケージのソースファイルとして「STATS.DPK」というファイルを生成します。コンパイラは「STATS.DPL」という実行可能ファイルおよび「STATS.DCP」というバイナリイメージを生成します。このパッケージをほかのパッケージの requires 節で参照する場合やアプリケーションで使う場合に，「STATS」を使います。

［パッケージの説明(D)］	パッケージの概要です。


既存のパッケージへのインストール
既存のパッケージへのインストール1026005

［ユニットファイル名(U)］	インストールするユニットの名前を入力します。ユニットが［検索パス(S)］に表示されている場合，フルパス名の入力は不要です。ユニットディレクトリが［検索パス(S)］に表示されていない場合，そのディレクトリはパスの最後に追加されます。

［検索パス(S)］	ファイルの検索で使われるパスです。

［パッケージファイル名(P)］	インストールされているパッケージの名前をドロップダウンリストで選択するか，ほかの既存のパッケージの名前を入力します。

［パッケージの説明(D)］	選択したパッケージの概要です。


参照
参照1026006

パッケージについて


コンポーネント(C)｜ActiveX コントロールの取り込み(X)
コンポーネント(C)｜ActiveX コントロールの取り込み(X)1026007

参照

［ActiveX コントロールの取り込み］ダイアログボックスにはシステムに登録されている ActiveX コントロールが表示されます。このダイアログボックスで Delphi プロジェクトにこれらのコントロールを追加します。.PAS ファイルに Pascal の宣言を生成すると，これらのどのコントロールでも，ネイティブな VCL オブジェクトの場合と同じように使うことができます。実際には，ActiveX コントロールは Delphi ラッパー内に配置されます。このダイアログボックスの上部には，現在登録されていて Delphi にインポートできるコントロールのリストが表示されます。このリストでは，既存のコントロールから Pascal の宣言を取り出せます。また，［ActiveX コントロールの取り込み］ダイアログボックスでは，新しいコントロールをインポートできるようにそれらを適宜に登録できます。

新しい ActiveX コントロールを追加して登録するには

1.	［追加(A)］をクリックします。［ActiveX コントロールの登録］ダイアログボックスが表示されます。

2.	［ActiveX コントロールの登録］ダイアログボックスで，追加するコントロールファイルのディスクまたはネットワーク上の場所に移動します。

3.	新しい ActiveX コントロールを選択します。選択した ActiveX コントロールは自動的にシステムに登録され，［ActiveX コントロールの取り込み］ダイアログボックスの使用可能コントロールのリストにすぐに表示されます。

［追加(A)］ボタン	新しい ActiveX コントロールを探し，Windows レジストリに登録するためのボタンです。この ActiveX コントロールは，Delphi にインポートできる登録済みオブジェクトのリストに表示されます。

［削除(R)］ボタン	登録されている ActiveX コントロールを削除するには，［削除(R)］ボタンをクリックします。コントロールは Windows レジストリから削除され，登録済みオブジェクトのリストからも削除されます。

［クラス名(C)］	選択されたライブラリ内の ActiveX コントロールクラスだけを表示します。

［パレットページ名(P)］	選択されたライブラリに関連付けられたオブジェクトのコンポーネントパレットでの位置を表示します。コントロールは機能別やベンダー別などでグループ化できます。

［ユニットディレクトリ名(D)］	このコントロールを使うユニットが入るディレクトリの名前を表示します。パスのルートだけが表示され，ファイル名は表示されません。ユニット名は内部タイプライブラリ名から得られます。ディレクトリツリーを上へ移動するには，［...］ボタンをクリックします。ユニットディレクトリ名が［検索パス(S)］に表示されていない場合，そのディレクトリはパスの最後に追加されます。

［検索パス(S)］	ファイルの検索で使われるパスを表示します。

［インストール(I)］	ユニットを作成し，パッケージエディタを開き，指定されたパッケージにユニットをインストールします。［インストール(I)］をクリックすると，パッケージエディタが表示され，新規ユニットをデフォルトの Delphi パッケージにインストールするか，ほかのパッケージを作成してそこに新規ユニットを入れるかを尋ねられます。パッケージエディタから［ActiveX コントロールの取り込み］ダイアログボックスを開いた場合，このボタンは表示されません。

［ユニットの作成(U)］	ユニットを作成し，ユニットコードをコードエディタに表示します。ユニットは現在のプロジェクトには入りません。パッケージエディタから［ActiveX コントロールの取り込み］ダイアログボックスを開いた場合，このボタンは表示されません。


参照
参照1026008

ActiveX コントロール


コンポーネント(C)｜コンポーネントテンプレートの作成(T)
コンポーネント(C)｜コンポーネントテンプレートの作成(T)1026009

参照

カスタムコンポーネントテンプレートを作成するには

1.	作成の起点となる既存のコンポーネントを選択し，フォームに配置します。

2.	コンポーネントを選択して，オブジェクトインスペクタでテンプレート用にプロパティとイベントを設定します。たとえば，標準的な外観を必要とするフォームで使う StaticText コンポーネントを作成する場合，このコンポーネントの Font プロパティと Color プロパティを設定します。

3.	目的のコンポーネントを選択したままで，［コンポーネント(C)｜コンポーネントテンプレートの作成(T)］を選択して，カスタムテンプレートに新しい名前，パレットでの位置，およびアイコンを指定します。

［コンポーネント名(C)］	この項目には，現在選択されているコンポーネントの名前にサフィックスとして「template」が付いたものが表示されます。

［パレットページ名(P)］	このボタンをクリックして，新しいコンポーネントを表示するタブ付きの Delphi パレットを選択します。

［パレットアイコン］	この項目には，現在選択されているコンポーネントのアイコンが表示されます。アイコンを変更するには，［変更(H)］ボタンをクリックし，［ファイルを開く］ダイアログボックスでイメージのディレクトリを探し，アイコンの新しいイメージを選択します。新しいコンポーネントテンプレートを作成するために［OK］をクリックします。新しいテンプレートは，新しいアイコンとともに指定したタブ付きのパレットページにすぐに表示されます。


参照
参照1026010

コンポーネントテンプレートの作成と使い方


データベースメニュー
データベースメニュー1027001

データベースメニューのコマンドはデータベースの作成，変更，および表示を行うために使います。

エクスプローラ(E)

SQL モニタ(S)

フォームウィザード(F)


データベース(D)｜エクスプローラ(E)
データベース(D)｜エクスプローラ(E)1027002

［データベース(D)｜エクスプローラ(E)］を選択すると，Delphi のバージョンに応じてデータベースエクスプローラまたは SQL エクスプローラが開きます。どちらのツールでもデータと BDE エリアスの作成，表示，編集ができます。SQL エクスプローラでは，ローカルデータベースとリモートデータベースの問い合わせもできます。


データベース(D)｜SQL モニタ(S)
データベース(D)｜SQL モニタ(S)1027003

［データベース(D)｜SQL モニタ(S)］を選択すると SQL モニタが開きます。

SQL モニタでは，アプリケーションについて SQL のリソース割り当てなどのアクセス情報を監視できます。ただし，Delphi のバージョンによって SQL モニタを利用できる場合と利用できない場合があります。


データベース(D)｜フォームウィザード(F)
データベース(D)｜フォームウィザード(F)1027004

参照

［データベース(D)｜フォームウィザード(F)］を選択すると，Delphi のフォームウィザードを使ってローカルデータベースまたはリモートデータベースのデータを表示するフォームを作成できます。


参照1027005

フォームウィザードの使い方


フォームウィザードの使い方
フォームウィザードの使い方1027006

参照

フォームウィザードを使うと，InterBase，Paradox，dBASE，および Oracle のデータベースのデータを表示するフォームを簡単に作成できます。

作成するデータベースフォームの形式を選択します。

単一フォーム

マスター／リンクフォーム

［データセット］オプションを選択します。

TTableObject

TQueryObject

フォームウィザードは以下に示すフォーム構築のタスクを自動化しています。

フォームに Table コンポーネントと Query コンポーネントを接続する

Query コンポーネント用の SQL 文を記述する

対話型のコンポーネントと対話型でないコンポーネントをフォームに配置する

タブ順を定義する

DataSource コンポーネントを対話型コンポーネント，Table コンポーネント，および Query コンポーネントに接続する


参照1027007

フォームウィザードによるフォームの作成


フォームウィザードによるフォームの作成
フォームウィザードによるフォームの作成1027008

フォームウィザードを使って単純なデータベースフォームを作成できます。

フォームウィザードを使ってデータベースフォームを構築するには

1.	［データベース(D)｜フォームウィザード(F)］を選択してフォームウィザードを開きます。

2.	［フォームの形式］を選択します。

3.	［データセット］を選択し，［次>(N)］をクリックします。

4.	［ドライブ/エリアス名］リストからエリアスを選択します。

メモ:	 エリアスを作成していなくても，［データベースフォームウィザード］ダイアログボックスでデータベースへのパスを指定することでデータベース名を入力できます。

5.	作成するフォームで使うフィールドを選択します。

一部のフィールドだけを使うには

1.	〔Ctrl〕を押したままにします。

2.	［選択可能な項目(A)］リストから使いたいフィールドをそれぞれ選択します。

3.	［>］ボタンを選択します。

［選択可能な項目(A)］リストのすべてのフィールドを使うには

［>>］ボタンをクリックします。

［項目の表示順序(O)］リストからフィールドを削除するには

［<］ボタンまたは［<<］ボタンをクリックします。

［項目の表示順序(O)］リストのフィールドの順序を変更するには

1.	移動するフィールドを選択します。

2.	フィールドの位置を変更するために，上向きと下向きのボタンを使います。この練習の目的上［選択可能な項目(A)］リストのすべてのフィールドを使用してください。［次>(N)］を選択して次に進んでください。

3.	次のフォームウィザード画面は，選択したフィールドをフォームに表示するためのオプションを表しています。ウィザードには各選択肢の説明が示されます。この練習の目的上［垂直配置(V)］オプションを選択してください。

4.	フォームエキスパートは，縦方向のレイアウトを選択したときに生成されたフォームの各データ入力コンポーネントにテキストラベルを作成します。これらのラベルをデータ入力フィールドに関連して表示する方法を選択できます。画面には各選択肢の説明が示されます。この練習では［左(L)］オプションを選択し，［次>(N)］を選択して次に進んでください。

5.	［完了(F)］ボタンを選択してフォームを生成します。

フォームウィザードはいろいろな選択に従ってデータベースフォームを作成します。


編集メニュー
編集メニュー1028001

編集メニューコマンドのキーボードショートカット

編集メニューのコマンドはテキストとコンポーネントを設計時に処理するために使います。

元に戻す(U)	直前のアクションまたは削除操作を元に戻します。

やり直し(R)	［元に戻す(U)］を取り消します。

切り取り(T)	選択した項目を削除し，クリップボードに入れます。

コピー(C)	選択した項目のコピーをクリップボードへ入れ，項目は元の場所に残します。

貼り付け(P)	クリップボードの内容をコードエディタのウィンドウまたはフォームの中へコピーします。

削除(D)	選択した項目を削除します。

すべて選択(L)	フォーム上のすべてのコンポーネントを選択します。

グリッドに合わせる(G)	選択したコンポーネントをもっとも近いグリッドポイントへ揃えます。

前面に移動(F)	選択したコンポーネントを前に移動します。

背面に移動(B)	選択したコンポーネントを後ろに移動します。

位置合わせ(A)	コンポーネントを揃えます。

サイズ(S)	コンポーネントのサイズを変更します。

スケール(E)	フォーム上のすべてのコンポーネントのサイズを変更します。

タブ順序(R)	アクティブフォーム上にあるコンポーネントのタブ順を変更します。

作成順序(N)	非ビジュアルコンポーネントの作成順を変更します。

コントロールのロック(K)	フォーム上にあるすべてのコンポーネントを現在の位置に固定します。

インターフェースに追加(O)	ActiveX コンポーネントの新しいメソッド，イベント，またはプロパティを定義します。


編集(E)｜元に戻す(U)
編集(E)｜元に戻す(U)1028002

参照

コードエディタで［編集(E)｜元に戻す(U)］を選択すると，直前のキー入力またはマウスアクションを取り消して元に戻せます。フォームでの作業中に［編集(E)｜元に戻す(U)］を選択すると，直前に削除した項目を元に戻せます。

コードエディタでの［元に戻す(U)］の使い方

［元に戻す(U)］を使うと，削除した文字を再挿入したり，挿入した文字を削除したり，上書きした文字を元に戻したり，カーソルを元の位置へ戻したりできます。

［元に戻す(U)］を繰り返し選択すれば，複数のアクションを連続して元に戻せます。アクションを１ ステップずつさかのぼって変更を元に戻し，以前の状態を復元できます。元に戻す限度は［ツール(T)｜環境オプション(O)］で表示される［環境オプション］ダイアログボックスの［エディタ］ページで指定できます。

ブロック処理を元に戻した場合，ファイルはブロック処理をする前と同じ状態になります。

［元に戻す(U)］コマンドでは複数のウィンドウに影響するオプション設定の変更はできません。

［ツール(T)｜オプション(O)］で表示される［環境オプション］ダイアログボックスの［エディタ］ページで［グループ単位の取り消し(G)］にチェックマークを付けると，アクションのグループを元に戻せます。


参照1028003

編集(E)｜やり直し(R)

編集メニューコマンドのキーボードショートカット


編集(E)｜やり直し(R)
編集(E)｜やり直し(R)1028004

参照

［編集(E)｜やり直し(R)］を選択すると，直前に実行した［元に戻す(U)］を無効にできます。

［やり直し(R)］は［元に戻す(U)］コマンドの直後でだけ使えます。

フォームから削除したオブジェクトを元の場所に戻す場合には［やり直し(R)］は使えません。


参照1028005

編集(E)｜元に戻す(U)

編集メニューコマンドのキーボードショートカット


編集(E)｜切り取り(T)
編集(E)｜切り取り(T)1028006

参照

［編集(E)｜切り取り(T)］を選択すると，次の項目を現在の位置から削除してクリップボードへ入れることができます。

コードエディタで選択したテキスト

フォームのコンポーネント

メニューデザイナのメニュー

［切り取り(T)］を実行すると，現在のクリップボードの内容は選択した項目で置き換わります。

クリップボードの内容をほかの場所へ挿入するには
［編集(E)｜貼り付け(P)］を選択します。


参照1028007

編集メニューコマンドのキーボードショートカット


編集(E)｜コピー(C)
編集(E)｜コピー(C)1028008

参照

［編集(E)｜コピー(C)］を選択すると，選択したテキスト，コンポーネント，メニューのいずれかのコピーをクリップボードに入れることができます。コピー元はそのまま元の場所に残ります。［コピー(C)］を実行すると，現在のクリップボードの内容は選択した項目で置き換わります。

クリップボードの内容をほかの場所へ貼り付けるには
［編集(E)｜貼り付け(P)］を選択します。


編集(E)｜貼り付け(P)
編集(E)｜貼り付け(P)1028009

参照

［編集(E)｜貼り付け(P)］を選択すると，クリップボードの内容をコードエディタのアクティブページ，アクティブフォーム，メニューデザイナのアクティブメニューのいずれかへ挿入できます。

メモ:	テキストはコードエディタウィンドウへ，コンポーネントはフォームへ，メニュー項目はメニューデザイナへだけ貼り付けができます。

テキストをコードエディタウィンドウに貼り付けた場合，現在のカーソルの位置に挿入されます。

コンポーネントをフォームに貼り付けた場合，非ビジュアルコンポーネントはフォームの左上隅に貼り付けられ，ビジュアルコンポーネントは切り取り元またはコピー元での位置と同じ位置に貼り付けられます。

メニュー項目をメニューデザイナに貼り付けた場合，カーソル位置に挿入されます。

クリップボードの現在の内容は，新しい項目をクリップボードへ切り取るかコピーするまで何回でも貼り付けできます。


参照1028010

編集(E)｜コピー(C)

編集(E)｜切り取り(T)

編集メニューコマンドのキーボードショートカット


編集(E)｜削除(D)
編集(E)｜削除(D)1028011

［編集(E)｜削除(D)］を選択すると，クリップボードへコピーを入れずに，選択したテキストまたはコンポーネントを削除できます。

削除したテキストの貼り付けはできませんが，直後に［編集(E)｜元に戻す(U)］を選択すればテキストを復元できます。

［削除(D)］は項目を削除してもクリップボードの内容は上書きしたくない場合に使います。


編集(E)｜すべて選択(L)
編集(E)｜すべて選択(L)1028012

［編集(E)｜すべて選択(L)］を選択すると，アクティブフォームのすべてのコンポーネントを選択できます。すべてのコンポーネントを選択した場合，それらのコンポーネントに共通したプロパティだけがオブジェクトインスペクタの中に表示されます。


編集(E)｜グリッドに合わせる(A)
編集(E)｜グリッドに合わせる(A)1028013

［編集(E)｜グリッドに合わせる(G)］を選択すると，選択したコンポーネントをもっとも近いグリッド点に揃えます。

グリッドのサイズは［ツール(T)｜環境オプション(O)］で表示される［環境オプション］ダイアログボックスの［設定］ページで指定できます。


編集(E)｜前面に移動(F)
編集(E)｜前面に移動(F)1028014

参照

［編集(E)｜前面に移動(F)］を選択すると，選択したコンポーネントをフォーム上にあるほかのすべてのコンポーネントの前へ移動できます。この操作をコンポーネントの Z オーダーの変更といいます。

メモ:	［前面に移動(F)］コマンドと［背面に移動(B)］コマンドはウィンドウコンポーネントと非ウィンドウコンポーネントを組み合わせている場合には使えません。たとえば，ラベルの Z オーダーはボタンと関係しているので変更できません。


編集(E)｜背面に移動(B)
編集(E)｜背面に移動(B)1028015

参照

［編集(E)｜背面に移動(B)］を選択すると，選択したコンポーネントをフォーム上にあるほかのすべてのコンポーネントの後ろへ移動できます。この操作をコンポーネントの Z オーダーの変更といいます。

メモ:	［背面に移動(B)］コマンドと［前面に移動(F)］コマンドはウィンドウコンポーネントと非ウィンドウコンポーネントを組み合わせている場合には使えません。たとえば，ラベルの Z オーダーはボタンと関係しているので変更できません。


参照1028016

SendToBack メソッド


編集(E)｜位置合わせ(A)
編集(E)｜位置合わせ(A)1028017

参照

［編集(E)｜位置合わせ(A)］を選択すると，［位置合わせ］ダイアログボックスが開きます。

［位置合わせ］ダイアログボックス

このダイアログボックスは選択したコンポーネントをコンポーネント相互の相対関係またはフォームとの相対関係で整列させるために使います。

［水平位置合わせ］の位置合わせオプションはコンポーネントの右端，左端，中心線のいずれかにコンポーネントを揃える

［垂直位置合わせ］の位置合わせオプションはコンポーネントの上端，下端，中心線のいずれかにコンポーネントを揃える

水平または垂直の位置合わせオプションは次のとおりです。

オプション	説明

変更なし	コンポーネントの位置合わせを変更しない

左寄せ	選択したコンポーネントの左端を揃える (水平のみ)

中央に置く	選択したコンポーネントの中心を揃える

右寄せ	選択したコンポーネントの右端を揃える (水平のみ)

上に寄せる	選択したコンポーネントの上端を揃える (垂直のみ)

下に寄せる	選択したコンポーネントの下端を揃える (垂直のみ)

等間隔に配置	選択したコンポーネントを互いに等間隔で揃える

ウィンドウ中央に置く	選択したコンポーネントをウィンドウの中心に揃える


参照1028018

位置合わせパレット

コンポーネントの位置合わせ


編集(E)｜サイズ(S)
編集(E)｜サイズ(S)1028019

［編集(E)｜サイズ(S)］を選択すると，［サイズ］ダイアログボックスが開きます。

［サイズ］ダイアログボックス

このダイアログボックスは複数のコンポーネントを同じ高さと幅にサイズ変更するために使います。

［幅(W)］オプションは選択したコンポーネントの水平サイズを変更する

［高さ(T)］オプションは選択したコンポーネントの垂直サイズを変更する

水平または垂直のサイズ変更オプションは次のとおりです。

オプション	説明

変更なし	コンポーネントのサイズを変更しない

最小の幅に合わせる	コンポーネントグループのサイズを，選択したコンポーネントのうちの最小の幅に変更する

最小の高さに合わせる	コンポーネントグループのサイズを，選択したコンポーネントのうちの最小の高さに変更する

最大の幅に合わせる	コンポーネントグループのサイズを，選択したコンポーネントのうちの最大の幅に変更する

最大の高さに合わせる	コンポーネントグループのサイズを，選択したコンポーネントうちの最大の高さに変更する

幅	選択したコンポーネントの幅を数値で指定して設定する

高さ	選択したコンポーネントの高さを数値で指定して設定する


編集(E)｜スケール(E)
編集(E)｜スケール(E)1028020

［編集(E)｜スケール(E)］を選択すると，［スケール］ダイアログボックスが開きます。

［スケール］ダイアログボックス

このダイアログボックスはフォームとそのフォーム上のすべてのコンポーネントを正しい比率で拡大縮小するために使います。

［拡大倍率 (％単位) (S)］

フォームのサイズ変更を％単位で入力します。

100％を超えるとフォームが大きくなります。

100％未満だとフォームが小さくなります。


編集(E)｜タブ順序(R)
編集(E)｜タブ順序(R)1028021

参照

［編集(E)｜タブ順序(R)］を選択すると，［タブ順序の設定］ダイアログボックスが開きます。

このダイアログボックスは，フォーム上にあるコンポーネントのタブ順や，選択したコンポーネントの中に含まれている複数のコンポーネントのタブ順を変更するために使います。

［コントロールのタブ順一覧(C)］	アクティブフォーム上にあるコンポーネントを現在のタブ順に表示します。最初に表示されるコンポーネントが，タブ順で最初のコンポーネントです。デフォルトのタブ順はコンポーネントをフォーム上に配置した順によって決まります。

上矢印	［コントロールのタブ順一覧(C)］リストボックスで選択したコンポーネントのタブ順を上へ移動する場合に上矢印のボタンをクリックします。

下矢印	［コントロールのタブ順一覧(C)］リストボックスで選択したコンポーネントのタブ順を下へ移動する場合に下矢印のボタンをクリックします。

コンポーネントのタブ順を変更するには

1.	コンポーネント名を 1 つ選択します。

2.	そのコンポーネントのタブ順を上へ移動したい場合は上矢印のボタンを，下へ移動したい場合は下矢印をクリックします。

選択したコンポーネントをタブ順の中の新しい位置までドラッグすることもできます。

3.	変更を保存するため［OK］をクリックします。


参照1028022

タブ順の設定


編集(E)｜作成順序(N)
編集(E)｜作成順序(N)1028023

［編集(E)｜作成順序(N)］を選択すると，［作成順序］ダイアログボックスが開きます。

［作成順序］ダイアログボックス

このダイアログボックスは設計時または実行時にフォームをロードしたときにアプリケーションによって非ビジュアルコンポーネントが作成される順序を指定するために使います。

リストボックスにはアクティブフォーム上にある非ビジュアルコンポーネントと，それらの種類，現在の作成順が表示されます。デフォルトの作成順は非ビジュアルコンポーネントをフォーム上に配置した順によって決まります。

作成順を変更するには

1.	コンポーネント名を 1 つ選択します。

2.	そのコンポーネントの作成順を上へ移動したい場合は上矢印のボタンを，下へ移動したい場合は下矢印をクリックします。

選択したコンポーネントを作成順の中の新しい位置までドラッグすることもできます。

3.	変更を保存するため［OK］をクリックします。


編集(E)｜コントロールのロック(K)
編集(E)｜コントロールのロック(K)1028024

［編集(E)｜コントロールのロック(K)］を選択すると，アクティブフォーム上にあるすべてのコンポーネントを現在の位置に固定できます。このコマンドにチェックマークが付いているときはコントロールの移動やサイズ変更ができません。ただし，オブジェクトインスペクタを使えば，選択したコントロールの Height，Left，Top，Width の各プロパティを編集できます。

このコマンドにチェックマークを付けると，コントロールがロックされます。コントロールがロックされているときに［コントロールのロック(K)］を選択すればロックを解除できます。

メモ:	［コントロールのロック(K)］はフォーム自体に対しては無効です。［コントロールのロック(K)］を選択している場合でもフォームのサイズ変更や移動はできます。


インターフェースに追加(O)
編集(E)｜インターフェースに追加(O)1028025

参照

［編集(E)｜インターフェースに追加(O)］を選択すると，ActiveX コンポーネントの新しい手続き，関数，またはプロパティを定義できます。これらの要素は ActiveX コンポーネントのインターフェースに追加され，ほかのアプリケーションから利用できるようになります。ActiveX コンポーネントが使うインターフェースメンバーをこのコマンドで簡単に宣言できます。

ActiveX 実装ファイルを右クリックし，スピードメニューから［インターフェースに追加(O)］を選択することもできます。

［編集(E)｜インターフェースに追加(O)］コマンドを選択すると［インターフェースに追加］ダイアログボックスが表示されます。このダイアログボックスでインターフェースメンバーの種類（プロパティ，メソッド，イベントなど）を選択し，選択した種類の宣言をすぐに入力できます。

宣言ボックスで入力した内容の構文を自動的に検査するには
［構文の支援］チェックボックスをクリックします。

［OK］をクリックすると，入力した宣言が以下に示す 3 つの必須の保存場所に自動的に格納されます。

現在の ActiveX 実装ユニット

ActiveX タイプライブラリ（TLB ファイル）

Delphi タイプライブラリ（DTL ファイル）

この時点で，実装ユニットでメソッドの実際の Pascal コードを記述したり，プロパティを設定したりできます。


参照
参照1028026

編集メニューコマンドのキーボードショートカット


ファイルメニュー
ファイルメニュー1029001

参照

［ファイル］メニューは，新規または既存のプロジェクトおよびファイルを開き，保存し，閉じ，印刷し，また開いているプロジェクトに新しいフォームやユニットを追加するために使います。

［ファイル］メニューのコマンド	説明

新規作成(N)	新しく作成できる項目が入っている［新規作成］ダイアログボックスを開く

アプリケーションの新規作成(T)	フォーム，ユニット，.DPR ファイルが入っている新しいプロジェクトを作成する

フォームの新規作成(F)	空白フォームを作成してプロジェクトに追加する

データモジュールの新規作成(M)	新しい空白データモジュールを作成してプロジェクトに追加する

開く(O)	［開く］ダイアログボックスを使って既存のプロジェクト，フォーム，ユニット，またはテキストファイルをコードエディタに読み込む

開き直す(R)	最近閉じたプロジェクトとモジュールの入っているカスケードメニューを表示する

上書き保存(S)	現在のファイルを現在の名前で保存する

名前を付けて保存(A)	プロジェクトのファイルに対する変更も含めて，現在のファイルを新しい名前で保存する

プロジェクトに名前を付けて保存(E)	現在のプロジェクトを新しい名前で保存する

すべて保存(V)	現在のプロジェクトとモジュール両方の開いているすべてのファイルを保存する

閉じる(C)	現在のプロジェクトとそれに関連付けられているユニットとフォームを閉じる

すべて閉じる(L)	開いているすべてのファイルを閉じる

ユニットを使う(U)	選択しているユニットをアクティブなモジュールの uses 節に追加する

プロジェクトに追加(D)	既存のファイルをプロジェクトに追加する

プロジェクトから削除(J)	プロジェクトからファイルを削除する

印刷(P)	アクティブなファイルをプリンタに送る

終了(X)	開いているプロジェクトを閉じて Delphi を終了する


参照1029002

ファイルメニューコマンドのキーボードショートカット


ファイル(F)｜新規作成(N)
ファイル(F)｜新規作成(N)1029003

参照

［新規作成］ダイアログボックスではテンプレートにアクセスしたり，Delphi のオブジェクトリポジトリの［フォーム］，［ダイアログ］，［プロジェクト］，［業務］の各ページにアクセスしたりできます。［新規作成］ダイアログボックスにはテンプレートまたはオブジェクトリポジトリページのカテゴリごとのタブがあります。オブジェクトリポジトリにはフォーム，プロジェクト，ウィザードが入っています。これらのオブジェクトは直接使ったり，プロジェクトにコピーしたりできます。既存のオブジェクトからの継承もできます。どれができるかはオブジェクトの種類によって異なります。たとえば，ウィザードでできるのはコピーだけです。


参照1029004

ファイル(F)｜上書き保存(S)

ファイル(F)｜開く(O)

プロジェクトの管理

ツール(T)｜リポジトリ(R)


ファイル(F)｜アプリケーションの新規作成(T)
ファイル(F)｜アプリケーションの新規作成(T)1029005

［ファイル(F)｜アプリケーションの新規作成(T)］を選択して Delphi の新しいプロジェクトを作成します。

標準の空白プロジェクトだけでなく，カスタムプロジェクトをデフォルトプロジェクトとして指定することもできます。

ある時点で開いておけるプロジェクトは 1 つだけです。［ファイル(F)｜アプリケーションの新規作成(T)］を選択したときにプロジェクトが開いていた場合，現在のプロジェクトに対する変更を保存するよう求められます。

新しいプロジェクトは次のものから構成されます。

新しいプロジェクトファイル (PROJECT1.DPR)

新しいフォームファイル (FORM1.DFM)，およびそれに関連付けられたフォームユニット (UNIT1.PAS)

プロジェクトファイルとユニットファイルの名前は保存するときに変更できます。

デフォルトプロジェクトを再定義するには

1.	［ツール(T)｜リポジトリ(R)］を選択して［オブジェクトリポジトリ］ダイアログボックスを開きます。

2.	［ページ(P)］リストボックスで［プロジェクト］をクリックします。

［オブジェクト(O)］リストボックスにプロジェクトのリストが表示されます。

3.	デフォルトプロジェクトにしたいプロジェクトを選択します。

4.	［プロジェクトの新規作成時に使用(Q)］チェックボックスを選択します。

5.	［OK］をクリックします。

以上の手順で指定したデフォルトプロジェクトは［アプリケーションの新規作成(T)］コマンドを選択したときに使われます。


ファイル(F)｜フォームの新規作成(F)
ファイル(F)｜フォームの新規作成(F)1029006

［ファイル(F)｜フォームの新規作成(F)］を選択すると，ブランクフォームと新しいユニットを作成してプロジェクトに追加できます。

新しいフォームを作成すると， 新しいフォームとそれに関連付けられているユニットファイルが，開いているプロジェクトに含まれるファイルのリストに自動的に追加されます。開いているプロジェクトがない場合は空白フォームが作成されます。

デフォルトフォームを再定義しなかった場合，新しいフォームのタイトルは FormXX となり，新しいユニットは UnitXX.PAS になります。XX はフォームとユニットの番号を表します。最初のフォームであれば Form1，2 番目なら Form2，のようになります。

フォームの名前を変更するには
オブジェクトインスペクタで Name プロパティを編集します。

ユニットの名前を変更するには
［ファイル(F)｜名前を付けて保存(A)］でファイルを保存するか， ［ファイル(F)｜プロジェクトに名前を付けて保存(P)］でプロジェクト全体を保存します。

フォームまたはユニットの名前の変更は，ソースコード全体に渡ってそのユニットの名前が使われているすべての個所に反映されます。

デフォルトとしてカスタムフォームを指定することもできます。

デフォルトフォームを再定義するには

1.	［ツール(T)｜リポジトリ(R)］を選択して［オブジェクトリポジトリ］ダイアログボックスを開きます。

2.	［ページ(P)］リストボックスで［フォーム］または［ダイアログ］をクリックします。

［オブジェクト(O)］リストボックスに項目のリストが表示されます。

3.	デフォルトフォームにしたいフォームを選択します。

4.	［フォームの新規作成時に使用(N)］チェックボックスを選択します。

5.	［OK］をクリックします。

以上の手順で指定したデフォルトプロジェクトは［フォームの新規作成(F)］コマンドを選択したときに使われます。


参照

フォーム，基本構築ブロック


ファイル(F)｜データモジュールの新規作成(M)
ファイル(F)｜データモジュールの新規作成(M)1029007

参照

［ファイル(F)｜データモジュールの新規作成(M)］を選択してプロジェクトに新しいデータモジュールを追加します。IDE のデスクトップにデータモジュールコンテナが表示され，データモジュールがプロジェクトファイルに追加されます。

設計時にはデータモジュールは，背景が白で位置合わせグリッドのない Delphi の標準フォームのように見えます。フォームの場合と同じように，コンポーネントパレットから非ビジュアルコンポーネントをモジュールに配置でき，追加したコンポーネントに合わせてデータモジュールのサイズを変更できます。


参照
参照1029008

新しいデータモジュールの作成

データモジュールとユニットファイルの命名

オブジェクトリポジトリ内のデータモジュールの再利用

オブジェクトの共有

コピー(C)，継承(I)，直接使用(U)

データモジュールの継承

データモジュールの使い方

オブジェクトリポジトリへのデータモジュールの追加


新規作成ダイアログボックス
新規作成ダイアログボックス1029009

参照

［新規作成］ダイアログボックスを使って，アプリケーション開発の出発点として使えるフォーム，プロジェクトテンプレート，またはウィザードを選択します。［新規作成］ダイアログボックスから，Delphi のオブジェクトリポジトリの中を見ることができます。オブジェクトリポジトリにはフォーム，プロジェクト，およびウィザードが入っています。これらのオブジェクトは，直接使ったり，プロジェクトにコピーしたり，また既存のオブジェクトから継承したりすることができます。

［新規作成］ダイアログボックスから新しいフォームを追加するには

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［フォーム］ページまたは［ダイアログ］ページから追加したい項目が入っているタブを選択します。

3.	追加したいフォームの種類を表すリストビューから項目を選択します。

4.	新しいフォームをコピーするか，継承するか，直接使うかを選択します。

プロジェクトテンプレートから新しいプロジェクトを開始するには

［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

1.	［プロジェクト］タブを選択します。

2.	使いたいプロジェクトテンプレートを選択して［OK］を選択します。または，アプリケーションウィザードを選択してカスタムテンプレートを定義します。

3.	［ディレクトリの選択］ダイアログボックスで新しいプロジェクトのファイル用のディレクトリを指定します。

プロジェクトテンプレートのコピーが指定されたディレクトリに開きます。または，アプリケーションウィザードでディレクトリ名の入力を求められます。

項目の説明を表示するには

1.	［ファイル(F)｜新規作成(N)］を選択します。

2.	［新規作成］ダイアログボックスから項目を選択します。

3.	右クリックします。

4.	コンテキストメニューから［詳細表示(D)］を選択します。

［コメント］列に項目の説明が表示されます。

［新規作成］ダイアログボックスのページ

Delphi を最初にインストールしたときには［新規作成］ダイアログボックスには8 つのページがあります。各ページにはプロジェクトに取り込める項目があります。これらのページのうち次の 3 つは固定のページで，標準の Delphi コンポーネントを提供します。

新規作成

ActiveX

現在のプロジェクト

残りのページは，オブジェクトリポジトリからのフォーム，プロジェクト，データモジュール，ウィザードの入ったユーザー定義のページです。デフォルトでは［新規作成］ダイアログボックスには次のユーザー定義ページがあります。

フォーム

ダイアログ

プロジェクト

データモジュール

業務

ページを右クリックして［詳細表示(D)］を選択すると，各項目の説明が表示されます。

新規作成コンテキストメニュー

［新規作成］ダイアログボックスを右クリックするとコンテキストメニューが表示されます。コンテキストメニューで表示をカスタマイズできます。

メモ:	［オブジェクトリポジトリ］ダイアログボックスを開くには，コンテキストメニューで［プロパティ(R)］を選択します。このダイアログボックスを使ってオブジェクトリポジトリ内の項目の編集，ページの追加，項目名の変更が行えます。

使い方のオプション

リポジトリ内のオブジェクトをプロジェクトに取り込む方法のオプションが 3 つあります。指定したオブジェクトで使えないオプションは淡色表示になります。

項目をコピーする

項目から継承する

項目を直接使う

項目のコピー

項目をコピーするとその正確な複製が得られ，その項目がフォームまたはデータモジュールであればプロジェクトに追加されます。オブジェクトリポジトリ内のその項目を変更しても，プロジェクト内のコピーには反映されません。また，プロジェクト内のコピーに対する変更もリポジトリ内の元の項目には影響しません。

メモ: 	プロジェクトテンプレートを使うときに利用できるオプションはコピーだけです。フォームウィザードまたはプロジェクトウィザードに対してはコピーオプションしか使えません。ウィザードを使うと共有されるコードは実際には追加されず，独自のコードを生成するプロセスが実行されます。

項目の継承

もっとも柔軟性があって強力なオプションが項目の継承です。項目を継承すると，その項目から新しいクラスが派生してプロジェクトに追加されます。プロジェクトを再コンパイルすると，特定の部分を変更していなければ，オブジェクトリポジトリ内の項目に対する変更は派生クラスに反映されます。派生クラスに対する変更はオブジェクトリポジトリ内の共有項目には影響しません。

メモ:	継承は，フォーム，ダイアログボックス，およびデータモジュールにはオプションとして使えますが，プロジェクトテンプレートには使えません。同じプロジェクト内の項目を再使用する場合に使えるオプションは継承だけです。

項目の直接使用

項目の直接使用オプションは，主にデータモジュールに対して使います。項目を直接使うと，その項目はプロジェクトの一部として作成したのと同じようにプロジェクトに追加されます。その項目に対する設計時の変更は，その項目を直接使っている，あるいはその項目を継承しているすべてのプロジェクトに反映されます。

メモ:	項目の直接使用は，フォーム，ダイアログボックス，およびデータモジュールに対して使えるオプションです。直接使用の項目への変更は実行時にだけ行い，ほかのモジュールに影響する変更が行われないようにしてください。


参照1029010

ツール(T)｜リポジトリ(R)


新規作成
新規作成1029011

項目	説明

アプリケーション	フォーム，ユニット，および .DPR の入った新しいプロジェクトを作成する，あるいはテンプレートを選択できるようにする
コンポーネント	コンポーネントウィザードを使って新しいコンポーネントを作成する
データモジュール	非ビジュアルコンポーネントとビジネスルール用のリポジトリとして使える新しいデータモジュールを作成する
ダイナミックリンクライブラリ	新しい DLL プロジェクトを作成する
フォーム	空白フォームを作成して現在のプロジェクトに追加する，あるいはフォームテンプレートを選択できるようにする
パッケージ	新しいパッケージを作成する。［パッケージの新規作成］ダイアログボックスを表示して，新しいパッケージのファイル名と説明を指定する。新しいパッケージはパッケージエディタに表示される
リモートデータオブジェクト	新しいリモートデータモジュールを作成する。リモートデータモジュールは，マルチ階層データベース環境でクライアントとサーバー間のアプリケーションサーバーに存在する OLE オートメーションオブジェクト。リモートデータセットウィザードで，新しいリモートデータモジュールのクラス名の入力とインスタンスの種類の設定ができる
テキスト	新しいテキストファイルを作成する
スレッドオブジェクト	新しいスレッドオブジェクトを作成する
ユニット	新しいユニットを作成して現在のプロジェクトに追加する
Web サーバーアプリケーション	新しい Web サーバーアプリケーション (DLL または EXE) を作成する
レポート	新しい QuickReport オブジェクトを作成する


ActiveX
ActiveX1029012

このページのオブジェクトをクリックして，新しい Active フォーム，ActiveX コントロール，プロパティページ (ActiveX コントロール用)，タイプライブラリ (ActiveX コントロールまたは OLE オートメーションオブジェクト用) を作成します。

項目	説明

Active フォーム	新しい Active フォームを作成する。Active フォームは Web ブラウザで動作するようにあらかじめ設定されている，単純化された ActiveX コントロール (TActiveForm から派生する)。ActiveX コントロールウィザードに示される作成方法に従って，コントロールをフォームに追加できる。このウィザードでは，必要であれば ActiveX ライブラリプロジェクトが作成され，タイプライブラリ，フォーム，実装ユニットが作成される。対応するタイプライブラリ宣言を含むユニットも作成される。 ほかの ActiveX コントロールとは異なり，構築済みの Active フォームのプロパティは，追加コードによってパブリッシュに設定しない限り開発環境で変更することはできない
ActiveX コントロール	新しい ActiveX コントロールを作成する。ActiveX コントロールウィザードに示される作成方法に従って，新しいコントロールの基礎となる VCL オブジェクトを選択する。ActiveX コントロールは，インターフェースとメソッド引数をクライアントアプリケーションに定義するために ActiveX ライブラリが必要
ActiveX ライブラリ	新しい ActiveX ライブラリを作成する。ベースとなる Project1.dpr というテンプレートファイルが作成される。新しい ActiveX コントロールを追加するには，ActiveX ライブラリプロジェクトをあらかじめ開いておかなければならない
オートメーションオブジェクト	新しい OLE オートメーションオブジェクトを作成する。オートメーションオブジェクトウィザードで，新しいオートメーションオブジェクトのクラス名の入力とインスタンスの種類の設定ができる。新しいオートメーションオブジェクトを追加するには，ActiveX ライブラリプロジェクトをあらかじめ開いておかなければならない
タイプライブラリ	ActiveX コントロールまたは OLE オートメーションオブジェクトの型情報のライブラリを作成または編集する。タイプライブラリエディタが表示される
プロパティページ	ActiveX プロパティページとして設定される .pas ファイルを作成する。プロパティページは設計モードで表示され，プライベート宣言とパブリック宣言を追加できるようになっている。フォームウィンドウでダイアログボックスを設計し，プロパティをグループ化すると，開発者はコントロールをアプリケーションに実装する場合に簡単に変更できる


現在のプロジェクト
現在のプロジェクト1029013

プロジェクトが開いていれば［新規作成］ダイアログボックスの 2 番目のページは現在のプロジェクトのページです。現在のプロジェクトタイトルがタブに表示されます。現在のプロジェクトのページにはプロジェクトのすべてのフォームが入っています。既存のプロジェクトのどのフォームからでも継承フォームを作成できます。


ディレクトリの選択ダイアログボックス
ディレクトリの選択ダイアログボックス1029014

［ディレクトリの選択］ダイアログボックスは新しいプロジェクトの作業用ディレクトリを選択するために使います。

［ディレクトリの選択］ダイアログボックスを開くには
［ファイル(F)｜新規作成(N)］で［プロジェクト］タブを選択し，空白でないプロジェクトテンプレートを選択します。

［ディレクトリ名(N)］	カレントディレクトリを表示します。存在しないディレクトリを入力すると，そのディレクトリが作成されます。

［ディレクトリ(D)］	ディレクトリを一覧表示します。

［ファイル(F): (*.*)］	カレントディレクトリにあるすべてのファイルを一覧表示します。ファイルの選択はできません。このファイルリストは単にカレントディレクトリの内容を知らせるために表示されます。

［ドライブ(R)］	使用可能なすべてのドライブを一覧表示します。使用可能ドライブのいずれかを選択できます。


ファイル(F)｜開く(O)
ファイル(F)｜開く(O)1029015

［ファイル(F)｜開く(O)］を選択すると［開く］ダイアログボックスが開きます。

［開く］ダイアログボックス

［開く］ダイアログボックスは既存のプロジェクト，フォーム，ユニット，またはテキストファイルをコードエディタに読み込むために使います。

開いただけでは，ファイルは自動的には現在のプロジェクトに追加されません。ファイルをプロジェクトに追加するには［ファイル(F)｜プロジェクトに追加(D)］を選択します。

複数のフォーム，ユニット，テキストファイルを開くことができますが，プロジェクトは同時に 1 つしか開くことができません。

［ファイル(F)｜開く(O)］でプロジェクトファイルを選択したときに別のプロジェクトが開いていると，現在のプロジェクトへの変更を保存するよう求められます。

［保存する場所(I)］	カレントディレクトリを表示します。ドロップダウンリストを使って別のドライブやディレクトリを選択します。

［ファイル］	カレントディレクトリにあるファイルのうち，［ファイル名(N)］のワイルドカードまたは［ファイルの種類(T)］のファイルの種類に一致するファイルを表示します。ファイルの一覧を表示する (デフォルト) か，各ファイルの詳細を表示できます。

［ファイル名(N)］	読み込みたいファイルの名前または［ファイル］リストボックスでフィルタとして使うワイルドカードを入力します。

［ファイルの種類(T)］	開きたいファイルの種類を選択します。デフォルトはプロジェクトファイル (.DPR) です。カレントディレクトリにある選択した種類のすべてのファイルが［ファイル］リストボックスに表示されます。

［1 つ上のフォルダへ］	このボタンをクリックすると，ディレクトリのレベルがカレントディレクトリから 1 つ上がります。

［新しいフォルダの作成］	このボタンをクリックすると，カレントディレクトリ内に新しいサブディレクトリが作成されます。

［一覧］	このボタンをクリックすると，カレントディレクトリ内のファイルとディレクトリのリストが表示されます。

［詳細］	このボタンをクリックすると，ファイルとディレクトリのリストがタイムスタンプ，サイズ，属性の情報と一緒に表示されます。


ファイル(F)｜開き直す(R)
ファイル(F)｜開き直す(R)1029016

［ファイル(F)｜開き直す(R)］を選択すると以前に閉じたプロジェクトまたはモジュールをもう一度開くことができます。

プロジェクトまたはモジュールを閉じると，そのプロジェクトまたはモジュールは［開き直す(R)］リストに追加されます。

プロジェクトまたはモジュールをもう一度開くには

1.	［ファイル(F)｜開き直す(R)］を選択します。

2.	開きたいプロジェクトまたはモジュールをクリックします。

メモ:	［開き直す(R)］リストに表示されるのは［ファイル(F)｜閉じる(C)］コマンドで閉じたプロジェクトまたはモジュールだけです。保存された項目はリストに表示されません。


ファイル(F)｜上書き保存(S)
ファイル(F)｜上書き保存(S)1029017

［ファイル(F)｜上書き保存(S)］を選択すると，開いているプロジェクトに含まれるすべてのファイルへの変更が各ファイルの現在の名前で格納されます。

一度も保存していないプロジェクトファイルまたはユニットファイルがあるプロジェクトを保存するときには［名前を付けて保存］ダイアログボックスが開くので，新しいファイル名を入力します。

メモ:	開いているファイルでもプロジェクトに入っていないファイルは保存されません。このようなファイルを保存するには，コードエディタ内の各ファイルを選択して［ファイル(F)｜上書き保存(S)］を選択します。


ファイル(F)｜名前を付けて保存(A)
ファイル(F)｜名前を付けて保存(A)1029018

［ファイル(F)｜名前を付けて保存(A)］を選択するとアクティブなファイルを別の名前または別の場所に保存できます。

［名前を付けて保存］ダイアログボックス

［名前を付けて保存］ダイアログボックスはプロジェクトファイル名を変更したりプロジェクトを新しい場所に保存するために使います。ファイル名がすでに存在する場合は，既存のファイルを置き換えるかどうかが尋ねられます。

［保存する場所(I)］	カレントディレクトリを表示します。ドロップダウンリストを使って別のドライブやディレクトリを選択します。

［ファイル名(N)］	保存するファイルの名前を入力します。

［ファイル］	カレントディレクトリにあるファイルのうち，［ファイルの種類(T)］コンボボックスのファイルの種類に一致するファイルを表示します。

［ファイルの種類(T)］	ファイル拡張子を選択します。デフォルトは .DPR です。カレントディレクトリにある選択した種類のすべてのファイルが［ファイル］リストボックスに表示されます。プロジェクトファイルを別の拡張子で保存してもファイルの形式は変更されません。

［1 つ上のフォルダへ］	このボタンをクリックすると，ディレクトリのレベルがカレントディレクトリから 1 つ上がります。

［新しいフォルダの作成］	このボタンをクリックすると，カレントディレクトリ内に新しいサブディレクトリが作成されます。

［一覧］	このボタンをクリックすると，カレントディレクトリ内のファイルとディレクトリのリストが表示されます。

［詳細］	このボタンをクリックすると，ファイルとディレクトリのリストがタイムスタンプ，サイズ，属性の情報と一緒に表示されます。


ファイル(F)｜プロジェクトに名前を付けて保存(E)
ファイル(F)｜プロジェクトに名前を付けて保存(E)1029019

［ファイル(F)｜プロジェクトに名前を付けて保存(P)］を選択すると，プロジェクトファイル (.DPRファイル) を別の名前や別の場所に保存できます。このコマンドは .DPR ファイルや関連付けられたプロジェクトファイルをコピーしたり名前を変更するだけでなく，関連付けられたそれぞれのファイルを現在の場所へ現在の名前で保存します。

メモ:	ほかのプロジェクトで使われるフォームまたはユニットを変更して現在の変更をそれらのプロジェクトに反映させたくない場合は，このコマンドでプロジェクトを保存する前に［ファイル(F)｜名前を付けて保存(A)］を使ってそれぞれのユニットファイルのコピーと名前の変更をしなければなりません。

［プロジェクトに名前を付けて保存］ダイアログボックス

［プロジェクトに名前を付けて保存］ダイアログボックスはプロジェクトファイル名を変更したりプロジェクトを新しい場所に保存するために使います。ファイル名がすでに存在する場合，既存のファイルを置き換えるかどうかが尋ねられます。

［保存する場所(I)］	カレントディレクトリを表示します。ドロップダウンリストを使って別のドライブやディレクトリを選択します。

［ファイル名(N)］	保存するプロジェクトファイルの名前を入力します。

［ファイル］	カレントディレクトリにあるファイルのうち，［ファイルの種類(T)］コンボボックスのファイルの種類に一致するファイルを表示します。

［ファイルの種類(T)］	ファイル拡張子を選択します。デフォルトは .DPR です。カレントディレクトリにある選択した種類のすべてのファイルが［ファイル］リストボックスに表示されます。プロジェクトファイルを別の拡張子で保存してもファイルの形式は変更されません。

［1 つ上のフォルダへ］	このボタンをクリックすると，ディレクトリのレベルがカレントディレクトリから 1 つ上がります。

［新しいフォルダの作成］	このボタンをクリックすると，カレントディレクトリ内に新しいサブディレクトリが作成されます。

［一覧］	このボタンをクリックすると，カレントディレクトリ内のファイルとディレクトリのリストが表示されます。

［詳細］	このボタンをクリックすると，ファイルとディレクトリのリストがタイムスタンプ，サイズ，属性の情報と一緒に表示されます。


ファイル(F)｜すべて保存(V)
ファイル(F)｜すべて保存(V)1029020

［ファイル(F)｜すべて保存(V)］を選択すると，現在のプロジェクトとモジュールを含めて開いているすべてのファイルが保存されます。

以前に保存されていないファイルの場合

1.	［ファイル(F)｜すべて保存(V)］を選択します。

2.	［名前を付けて保存］ダイアログボックスに保存する項目のデフォルトの名前が表示されます。

3.	別の名前を使いたい場合は新しい名前を入力します。

4.	［保存(S)］をクリックします。

保存する次の項目のデフォルトの名前を示した［名前を付けて保存］ダイアログボックスが表示されます。

5.	すべてのモジュールの保存が終わるまで 3～4 の手順を繰り返します。


ファイル(F)｜閉じる(C)
ファイル(F)｜閉じる(C)1029021

［ファイル(F)｜閉じる(C)］を選択するとアクティブなウィンドウを閉じます。

フォームを閉じると関連付けられているユニットも閉じます。ファイルを閉じる前に変更を保存するかどうかが尋ねられます。以前にプロジェクトまたはファイルを保存していない場合は［名前を付けて保存］ダイアログボックスが開いて新しいファイル名を入力できます。

プロジェクトマネージャがアクティブウィンドウの場合，［ファイル(F)｜閉じる(C)］を選択すると，プロジェクト全体を閉じることができます。コードエディタ内のプロジェクトファイル (.dpr) を閉じた場合も，プロジェクト全体を閉じることになります。


ファイル(F)｜すべて閉じる(L)
ファイル(F)｜すべて閉じる(L)1029022

［ファイル(F)｜すべて閉じる(L)］を選択すると開いているすべてのファイルを閉じます。プロジェクトファイルとすべてのモジュールを閉じます。


ファイル(F)｜ユニットを使う(U)
ファイル(F)｜ユニットを使う(U)1029023

［ファイル(F)｜ユニットを使う(U)］を選択すると，既存のユニットをコードエディタ内の現在のユニットに入れることができます。このコマンドを使うと，現在のユニットから，選択したユニットのパブリックなオブジェクト，メソッド，関数，および手続きにアクセスできます。


ユニットを使うダイアログボックス
ユニットを使うダイアログボックス1029024

このダイアログボックスを使うと，指定したユニットの内容を現在のユニットで使えるようにできます。

ユニットを使うには

1.	［ファイル(F)｜ユニットを使う(U)］を選択します。

2.	［ユニットを使う］リストで，追加したいユニット名をクリックします。

3.	［OK］をクリックして，そのユニットを現在のユニットに追加します。

［ユニットを使う］リスト	プロジェクト内にある，現在のユニットが使っていないすべてのユニットが一覧表示されます。


ファイル(F)｜プロジェクトに追加(D)
ファイル(F)｜プロジェクトに追加(D) 1029025

参照

［ファイル(F)｜プロジェクトに追加(D)］を選択すると，［プロジェクトに追加］ダイアログボックスが開きます。

［プロジェクトに追加］ダイアログボックス

［プロジェクトに追加］ダイアログボックスは既存のユニットとそれに関連付けられたフォームを Delphi プロジェクトへ追加するために使います。ユニットをプロジェクトへ追加すると，そのユニットは自動的にプロジェクトファイルの uses 節へ追加されます。

［ファイルの場所(I)］	カレントディレクトリを表示します。ドロップダウンリストを使って別のドライブやディレクトリを選択します。

［ファイル名(N)］	読み込みたいファイルの名前または［ファイル］リストボックスでフィルタとして使うワイルドカードを入力します。

［ファイル］	カレントディレクトリにあるファイルのうち，［ファイル名(N)］編集ボックスのワイルドカードまたは［ファイルの種類(T)］コンボボックスのファイルの種類に一致するファイルを表示します。

［ファイルの種類(T)］	開きたいファイルの種類を選択します。デフォルトはソースファイル (.PAS) です。カレントディレクトリにある選択した種類のすべてのファイルが［ファイル］リストボックスに表示されます。

［1 つ上のフォルダへ］	このボタンをクリックすると，ディレクトリのレベルがカレントディレクトリから 1 つ上がります。

［新しいフォルダの作成］	このボタンをクリックすると，カレントディレクトリ内に新しいサブディレクトリが作成されます。

［一覧］	このボタンをクリックすると，カレントディレクトリ内のファイルとディレクトリのリストが表示されます。

［詳細］	このボタンをクリックすると，ファイルとディレクトリのリストがタイムスタンプ，サイズ，属性の情報と一緒に表示されます。


参照1029026

プロジェクトへのユニットとフォームの追加

ファイル(F)｜プロジェクトから削除(J)

プロジェクトの内容の表示と操作


ファイル(F)｜プロジェクトから削除(J)
ファイル(F)｜プロジェクトから削除(J)1029027

参照

［ファイル(F)｜プロジェクトから削除(J)］を選択すると，現在のプロジェクトからユニットを取り除くことができます。

［プロジェクトから削除］ダイアログボックス

このダイアログボックスは現在のプロジェクトから取り除くユニットを選択するために使います。ユニットを選択して［OK］をクリックすると，選択したユニットが現在のプロジェクトファイルの uses 節から取り除かれますが，ファイルがディスクから削除されるわけではありません。そのユニットへの参照を追加してある場合は，手作業でそれらの参照を取り除かなくてはなりません。

その編集セッションでファイルを変更した場合，そのフォームまたはユニットを別のプロジェクトで使う場合に備えて変更を保存するよう求められます。ファイルに変更を加えていない場合は，そのファイルはそのままプロジェクトから取り除かれます。

メモ:	ユニットファイルをほかのファイル管理プログラムを使って削除したり，DOS プロンプトから直接削除したりしないでください。エラーの原因になります。


参照1029028

ファイル(F)｜プロジェクトに追加(D)

プロジェクトからのユニットとフォームの削除

プロジェクトの内容の表示と操作


ファイル(F)｜印刷(P)
ファイル(F)｜印刷(P)1029029

［ファイル(F)｜印刷(P)］を選択すると，コードエディタのアクティブページまたはアクティブフォームを印刷できます。［ファイル(F)｜印刷(P)］を選択した場合，コードエディタとフォームのどちらがアクティブウィンドウであるかに応じて 2 つのダイアログボックスのどちらかが表示されます。

コードエディタがアクティブの場合，［選択部分の印刷］ダイアログボックスが表示される

フォームがアクティブの場合，［フォームの印刷］ダイアログボックスが表示される


フォームの印刷ダイアログボックス
フォームの印刷ダイアログボックス1029030

このダイアログボックスはフォームを印刷するときのスケールオプションを指定するために使います。スケールオプションはプリンタ用紙のサイズに応じて動作します。用紙のサイズは［プリンタの設定］ダイアログボックスの［サイズ(Z)］オプションを使って変更できます。

このダイアログボックスを表示するには，フォームがアクティブのときに［ファイル(F)｜印刷(P)］を選択します。

次の 3 つのスケールオプションがあります。

［画面の解像度で印刷(P)］ － PixelsPerInch プロパティの値を使ってフォームのスケールを設定する。PixelsPerInch の値によっては，フォームが複数のページにわたって印刷されることがある

［ページに収める(F)］ － 1 ページに収まるようにフォームのスケールを設定する

［プリンタの解像度で印刷(N)］ － 現在の画面上のサイズを使ってフォームを印刷する。このオプションを選択すると，フォームが複数のページにわたって印刷されることがある

［設定(T)］

［プリンタの設定］ダイアログボックスを表示するには，［設定(T)］ボタンをクリックします。


選択部分の印刷ダイアログボックス
選択部分の印刷ダイアログボックス1029031

このダイアログボックスはコードエディタのアクティブファイルを印刷するために使います。

［印刷するファイル］	印刷するファイルを表示します。表示されるファイルは［ファイル(F)｜印刷(P)］を選択したときにコードエディタでアクティブだったページです。

［選択範囲のみを印刷(P)］	選択したテキストブロックだけをプリンタへ送ります。このオプションはファイル内でテキストを選択してある場合にだけ使えます。このオプションにチェックマークを付けていないと，ファイル全体が印刷されます。

［ヘッダーとページ番号(N)］	各ページの上端にファイル名，現在の日付，ページ番号を入れます。

［行番号(L)］	左マージンに行番号を付けます。

［構文強調表示(S)］	太字，斜体，下線付き文字を使って構文の要素を強調表示します。

［カラー印刷(C)］	画面上の色に一致した色を印刷します (カラープリンタが必要です)。

［折り返し印刷(W)］	複数の行を使ってページ幅を超えた文字を印刷します。これを選択しなかった場合，コード行が切り捨てられ，ページ幅を超えた文字は印刷されません。

［左マージン(M)］	ページの左端から行頭までのマージンとして使う文字スペース数を指定します。

［設定(T)］	［設定(T)］をクリックすると，［プリンタの設定］ダイアログボックスが表示されます。


プリンタの設定ダイアログボックス
プリンタの設定ダイアログボックス1029032

プリンタオプションを変更し，リストでプリンタを選択します。このダイアログボックスを表示するには，［選択部分の印刷］ダイアログボックスで［設定(T)］をクリックします。

プリンタオプションの設定についての詳細は Windows のマニュアルを参照してください。

［名前(N)］	プリンタをリストボックスで選択します。

［縦(O)］	用紙の短い辺を横切るようにテキストを印刷します (たとえば 8.5 インチ× 11 インチ)。

［横(A)］	用紙の長い辺に沿ってテキストを印刷します (たとえば 11 インチ× 8.5 インチ)。

［サイズ(Z)］	用紙サイズを指定します。

［給紙方法(S)］	プリンタの用紙トレイ方式または用紙送り方式を指定します。

［プロパティ(P)］	現在選択されているプリンタの［プリンタ］プロパティページを表示します。


ファイル(F)｜終了(X)
ファイル(F)｜終了(X)1029033

［ファイル(F)｜終了(X)］を選択すると，開いたプロジェクトを閉じて Delphi を終了できます。

変更を保存する前に Delphi を終了しようとすると，変更を保存するかどうかが尋ねられます。


ヘルプメニュー
ヘルプメニュー1030001

［ヘルプ］メニューを使って，オンラインヘルプにアクセスします。これにより，特別なヘルプウィンドウが表示されます。

ヘルプシステムが提供する情報は，開発環境，ライブラリ，Object Pascal など，Delphi のすべての方面に渡っています。

ヘルプオプション	説明

［目次(C)］	［トピックの検索］ダイアログボックスを開く。このダイアログボックスでは，［目次］タブを選択するとトピックの階層リストが表示される。［キーワード］タブを選択するとトピックがアルファベット順に表示される。［テキスト検索］タブを選択するとヘルプシステムの全文検索を実行できる（Windows NT のみ）

［キーワード検索(K)］	［トピックの検索］ダイアログボックスを開く。このとき［キーワード］タブがすでに選択されている (［目次(C)］を参照)

［新機能］	Delphi 3.0 の新機能と拡張機能の概要を示す

［入門］	Delphi ユーザーインターフェースの主要機能と基本的なプログラミング作業についての説明を示す

［Object Pascal の使い方］	Object Pascal プログラミング言語の構文と意味についての説明を示す

［アプリケーション開発］	中級および上級のプログラミング作業についての詳細を示す。たとえばデータベースアプリケーション，カスタムコンポーネント，インターネットアプリケーション，イントラネットアプリケーションについての説明や，COM と ActiveX の操作方法についての説明を示す

［コンポーネントリファレンス］	ビジュアルコンポーネントライブラリ，型，ルーチン，変数，定数の完全なリファレンス

［Borland ホームページ］	ボーランドのホームページを開く

［Delphi ホームページ］	ボーランドの Delphi ホームページを開く

［Borland ユーザーサービス］	ボーランド社の WWW サイトにある Programs and Services ページへの直接的なリンク。ボーランド社が提供している教育，コンサルティング，テクニカルサポートなどのサービスについての説明を示すホームページ

［バージョン情報(A)...］	Delphi の著作権およびバージョンの情報


Form context menu
Form context menu1031001

See also

Use the Form context menu to manipulate components in the form at design time.

To display the Form context menu:

1.	On the form, select the component or components you want to manipulate.

Select a single component by clicking it. Select more than one by dragging across them or by holding down Shift while clicking each one.

2.	Right-click anywhere on the form, or press Alt-F10.

The following commands always appear on the Form context menu:

Align To Grid

Bring To Front

Send To Back	Revert To Inherited

Align

Size

Scale

Tab Order

Creation Order

Add To Repository

View As Text

Other commands appear on the Form context menu when you select certain components. For example when the Query component is selected the following commands are available:

Fields Editor

Define Parameters

Explore

Query Builder

Other context-sensitive commands:

Execute (BatchMove component)

Next Page (Notebook or TabbedNotebook component)

Previous Page (Notebook or TabbedNotebook component)

In addition, your installation of Delphi may have additional commands installed by a third party. To display help on a third-party command, display the Form context menu and select the command. This activates the module named in the command. Then, press F1 to get help on that module.


See also1031002

Form


Query Builder (Form context menu)
Query Builder (Form context menu)1031003

Choose Query Builder from the Form context menu when the Query component is selected, to open the Visual Query Builder. If a database is not already open, this command opens the Databases dialog box which enables you to select a database.


Execute (Form context menu)
Execute (Form context menu)1031004

See also

Choose Execute from the Form context menu when you have the BatchMove component selected, to perform at design time, the process specified in the Mode property.

The Mode property enables you to perform any of the following tasks:

Copy a dataset to a table.

Append a dataset to a table.

Update a table with data from a dataset.

Displaying data using data from a control.

To run this process at run time, you must call the Execute method for BatchMove.


See also1031005

Copying data and table structures

TBatchMove component


Edit Report (Form context menu)
Edit Report (Form context menu)1031006

See also

Choose Edit Report from the Form context menu when you have the Report component selected, to load ReportSmith and open the report you specified using the ReportName and ReportDir properties.

If you have not previously specified a report, Delphi opens the ReportSmith Open Report dialog box which enables you to select a report.

You can also perform this command by double-clicking the Report component on the form.


See also1031007

TReport component


Next Page (Form context menu)
Next Page (Form context menu)1031008

See also

Choose Next Page from the Form context menu when you have the either the Notebook component, or TabbedNotebook component selected, to set the ActivePage property to the next page in the notebook.

The next page is determined by the page order which you can specify using the Notebook editor.


See also1031009

Windows 3.1 components


Previous Page (Form context menu)
Previous Page (Form context menu)1031010

See also

Choose Previous Page from the Form context menu when you have the either the Notebook component, or TabbedNotebook component selected, to set the ActivePage property to the previous page of the notebook.

The previous page is determined by the page order which you can specify using the Notebook editor.


See also1031011

Windows 3.1 components


Align To Grid (Form context menu)
Align To Grid (Form context menu)1031012

Choose Align To Grid from the Form context menu to align the selected components to the closest grid point.

You can specify the size of the grid on the Preferences page of the Tools|Environment Options dialog box.

This command works the same as Edit|Align To Grid.


Bring To Front (Form context menu)
Bring To Front (Form context menu)1031013

See also

Choose Bring To Front from the Form context menu to move a selected component in front of all other components on the form.

This is called changing the component's z-order.

This command works the same as Edit|Bring To Front.


Send To Back (Form context menu)
Send To Back (Form context menu)1031014

See also

Choose Send To Back from the Form context menu to move a selected component behind all other components on the form.

This is called changing the component's z-order.

This command works the same as Edit|Send To Back.


Revert To Inherited (Form context menu)
Revert To Inherited (Form context menu)1031015

If a form inherits design features and properties from another form, you can choose Revert To Inherited from the Form context menu to restore the form to its original state. For example, if a form inherits a certain button placement from another form and you then move the button, Revert To Inherited returns the button to its orignal position.


Align (Form context menu)
Align (Form context menu)1031016

See also

Choose Align from the Form context menu to open the Alignment dialog box.

Use this dialog box to line up selected components in relation to each other or to the form:

This command works the same as Edit|Align.


Size (Form context menu)
Size (Form context menu)1031017

Choose Size from the Form context menu to open the Size dialog box.

Use this dialog box to resize multiple components to be exactly the same height or width.

This command works the same as Edit|Size.


Scale (Form context menu)
Scale (Form context menu)1031018

Choose Scale from the Form context menu to open the Scale dialog box.

Use this dialog box to proportionally resize the form and all of its components.

This command works the same as Edit|Scale.


Tab Order (Form context menu)
Tab Order (Form context menu)1031019

See also

Choose Tab Order from the Form context menu to open the Edit Tab Order dialog box.

Use this dialog box to modify the current tab order of the components on the active form or within the selected component if that component can contain other components.

This command works the same as Edit|Tab Order.


See also1031020

Setting the tab order


Creation Order (Form context menu)
Creation Order (Form context menu)1031021

Choose Creation Order from the Form context menu to open the Creation Order dialog box.

Use this dialog box to specify the order in which your application will create nonvisual components.

This command works the same as Edit|Creation Order.


Add To Repository (Form context menu)
Add To Repository (Form context menu)1031022

Choose Add To Repository from the Form context menu to open the Add To Repository dialog box. Use this command to easily add any form to the Object Repository.

Once you've designed a custom dialog box, you might want to reuse it in other projects. The best way to do this is to add the form to the Object Repository.

Saving a form as an object is similar to saving a copy of the form under a different name. When you save a form as a object, however, it then appears in the Object Repository.


View as Text (Forms context menu)
View As Text (Form context menu)1031023

Use this command to view a text description of the form�s attributes.

Note:	This command changes to View As From when you view the form as text.


View as Form
View As Form (Code Editor context menu)1031024

Use this command to view a unit as a form. This option is available only for units that can produce a form when the form is not already visible in the IDE.

Note:	This command changes to View As Text when you view the unit as a form.


Select Icon Dialog Box
Select Icon dialog box1031025

Use the Select Icon dialog box to choose a bitmap to represent your template in the New Items dialog box dialog box.

You can use a bitmap of any size, but it will be cropped to 60 x 40 pixels.

To open this dialog box:

Click the Browse button in the Add To Repository dialog box.


Project Manager context menu
Project Manager context menu1031026

See also

The Project Manager context menu contains commands that enable you to manage your project.

The commands on the Project Manager context menu are:

Save Project

Add Project To Repository

New Unit

New Form

Add File

Remove File

View Unit

View Form

View Project Source

Options

Update

To open the Project Manager context menu:

Choose View|Project Manager to open the Project Manager, then do one of the following:

Right-click anywhere on the Project Manager SpeedBar.

Press Alt+F10 when this is the active window.


See also1031027

Project Manager


Save Project (Project Manager context menu)
Save Project (Project Manager context menu)1031028

Choose Save Project from the Project Manager context menu to store changes made to all files in the open project using each file's current name.

If you try to save a project that has an unsaved project file or unit file, Delphi opens the Save As dialog box, where you enter the new file name.

This command works the same as File|Save Project.


Add To Repository (Project Manager context menu)
Add Project To Repository (Project Manager context menu)1031029

Choose Add Project To Repository from the Project Manager context menu to open the Add To Repository  dialog box.

You use the Add To Repository dialog box to add new forms to the Object Repository.

This command works the same as Project|Add To Repository.


Save Project Template dialog box
Add to Repository (Project)1031030

Use this dialog box to save a project template to the Object Repository.

After saving an application as a template, use the Edit Object Info dialog box to edit the description, delete the template, or change the bitmap.

Dialog box options

Title	Enter the name of the template. The maximum length for a title is 40 characters.

Description	Enter a description of the template. The description appears under the template name on the Select Template dialog box. The maximum length for a description is 255 characters.

Page	From the drop down list box, choose the name of the page (probably Projects) you want the template to appear on.

Author	Enter text indentifying the author of the application. Author information only appears when you select the View Details option from the context menu.

Template bitmap	Click the Browse button to open the Select Icon dialog box.  You can use a bitmap of any size, but it will be cropped to 60 x 40 pixels.


New Unit (Project Manager context menu)
New Unit (Project Manager context menu)1031031

Choose New Unit from the Project Manager context menu to create a new unit and add it to the project. When you add a new unit, the Code Editor becomes the active window and the new unit is the active page.

The new unit is titled UnitXX.PAS. XX represents the unit number. For example, the first form is Unit1, the second Unit2, and so on.

You can change the unit name by saving the file with File|Save As, or by saving the entire project using Save Project from the Project Manager context menu.  Changing a unit name by any other means might cause an error.

This command works the same as the File|New Unit.


New Form (Project Manager context menu)
New Form (Project Manager context menu)1031032

Choose New Form from the Project Manager context menu to create a blank form and a new unit and add them to the project.

The new form is titled FormXX and the new unit is UnitXX.PAS. (XX represents the form/unit number. For example, the first form is Form1, the second Form2, and so on.)

To change the name of the form,
Edit the Name property from the Object Inspector.

To change the unit name,
Save the file with File|Save As or save the entire project by using Save Project on the Project Manager context menu.

This command works the same as File|New Form.


Add File (Project Manager context menu)
Add File (Project Manager context menu)1031033

See also

Choose Add File from the Project Manager context menu to open the Add To Project dialog box.

Use the Add To Project dialog box to add an existing unit and its associated form to the Delphi project. When you add a unit to a project, Delphi automatically adds that unit to the uses clause of the project file.

This command works the same as Project|Add to Project.


See also1031034

Adding units and forms to a project

Remove file

Viewing and manipulating a project's contents


Remove File (Project Manager context menu)
Remove File (Project Manager context menu)1031035

See also

Choose Remove File from the Project Manager context menu to remove the module selected in the Project Manager from the uses clause of the current project file.

If you have modified the file you are removing during this editing session, Delphi prompts you to save your changes, just in case you want to use the form or unit in another project. If you have not modified the file, Delphi removes that file from the project without prompting you.

If a file has been modified during the current editing session, it is bold in the Project Manager.

Note:	Do not delete unit files by using other file management programs, or directly from the DOS prompt. Doing so causes errors.

This command works the same as File|Remove From Project.


See also1031036

Add File

Removing forms and units from a project

Viewing and manipulating a project's contents


View Unit (Project Manager context menu)
View Unit (Project Manager context menu)1031037

See also

Choose View Unit from the Project Manager context menu to make the selected module in the Project Manager the active page of the Code Editor. It also makes the Code Editor the active window.

If the module you want to view is not currently open, Delphi opens it.

This command works the same as View|Units.


See also1031038

Code Editor


View Form (Project Manager context menu)
View Form (Project Manager context menu)1031039

See also

Choose View Form from the Project Manager context menu to make the form associated with the module selected in the Project Manager the active window.

If the form you want to view is not currently open, Delphi opens it.

This command works the same as View|Forms.


View Project (Project Manager context menu)
View Project Source (Project Manager context menu)1031040

See also

Choose View Project Source from the Project Manager context menu to make the project file the active page in the Code Editor.

If the project file is not currently open, Delphi opens it.

This command works the same as View|Project Source.


Options (Project Manager context menu)
Options (Project Manager context menu)1031041

See also

Choose Options from the Project Manager context menu to open the Project|Options dialog box.

You can use this dialog box to set compiler directives.

This command works the same as the Project|Options.


See also1031042

Compiler directives


Update (Project Manager context menu)
Update (Project Manager context menu)1031043

Choose Update from the Project Manager context menu to synchronize any changes you have made directly in the project (.DPR) file itself.

Note:	This command remains disabled (dimmed) unless you have manually edited the project file. Because Delphi maintains the project file for you automatically, manually modifying the .DPR file is not recommended.


SpeedBar context menu
SpeedBar context menu1031044

See also

The SpeedBar context menu contains commands that enable you to edit or rearrange the buttons on the SpeedBar. You can also use the SpeedBar context menu to hide the SpeedBar.

The commands on the SpeedBar context menu are:

Show Hints

Hide

Help

Properties

To display the SpeedBar context menu:

Right-click anywhere on the SpeedBar.


See also1031045

SpeedBar


Properties (SpeedBar context menu)
Properties (SpeedBar context menu)1031046

See also

Choose Properties from the SpeedBar context menu to open the SpeedBar Editor dialog box.

SpeedBar editor

Use this dialog box to add buttons that represent menu commands to the SpeedBar, remove buttons from the SpeedBar, or rearrange buttons on the SpeedBar.

Dialog box options

Categories	Select a menu whose commands you want to add as buttons to the SpeedBar. The commands on the selected menu appear in the Command list box.

Command	Drag and drop a command from this list box onto the SpeedBar. The Commands list box displays all the commands available on the menu selected in the Categories list box. The icon to the left of the menu command shows how the button will appear on the SpeedBar.

Reset	Choose Reset to reset the SpeedBar to the default configuration.

When the SpeedBar editor is open, you can delete or rearrange any of the buttons currently on the SpeedBar; however, none of the buttons on the SpeedBar is active.


See also1031047

Configuring the SpeedBar

SpeedBar


Configuring the SpeedBar
Configuring the SpeedBar1031048

See also

The Delphi SpeedBar is configurable. That is, you can do any of the following:

Add buttons to the SpeedBar

Remove buttons from the SpeedBar

Rearrange the buttons on the SpeedBar

Before you can configure the SpeedBar, you must open the SpeedBar editor by choosing Properties from the SpeedBar context menu.

To add buttons to the SpeedBar:

1.	Enlarge the SpeedBar area by dragging the separator line between the SpeedBar and Component palette to the right. When you are over the separator line, the cursor turns into a horizontally split cursor.

2.	Select a menu from the Categories list box. The menu commands on the selected menu are displayed in the Commands list box.

3.	Drag the menu command you want to add from the Commands list box and drop it on the SpeedBar in an open space.

Note:	You can have overlapping buttons on the SpeedBar, but this is not advisable.

To remove a button from the SpeedBar:

Drag the button off the SpeedBar. An open space appears where the button was.

To rearrange the buttons on the SpeedBar:

Drag and drop the button to a new position.


See also1031049

SpeedBar


Hide (SpeedBar/Component Palette context menu)
Hide1031050

Select Hide to close the display.

When closed, an item can be redisplayed from the View menu.

Hide is available from the following Speed Menus:

Alignment Palette context menu

Component Palette context menu

Object Inspector context menu

SpeedBar context menu


Show Hints
Show Hints1031051

Choose Show Hints to toggle the display of Help Hints.  When this command is checked, Help Hints are enabled.

Show Hints is available from the following Speed Menus:

Alignment Palette context menu

Component Palette context menu

Object Inspector context menu

SpeedBar context menu


Help (SpeedBar context menu)
Help 1031052

Choose Help from the context menu to display Help for the item.

Help is available from the following:context menus :

Alignment Palette context menu

Component Palette context menu

Object Inspector context menu

SpeedBar context menu


Component Palette context menu
Component Palette context menu1031053

See also

The Component Palette context menu enables you to edit or rearrange the components on the Component palette. You can also use the Component Palette context menu to hide the Component palette.

Show Hints

Hide

Help

Properties

To display the Component Palette context menu:

Right-click anywhere on the SpeedBar.


See also1031054

Component palette


Configure (Component Palette context menu)
Properties (Component Palette context menu)1031055

See also

Choose Properties from the Component palette context menu to open the Palette page of the Tools | Environment Options dialog box.

Use this dialog box to rearrange the Components on the Component palette.


See also1031056

Component palette

Using design-time packages

Adding components to Delphi


Alignment Palette context menu
Alignment Palette context menu1031057

See also

The Alignment Palette context menu contains the following commands:

Stay On Top

Show Hints

Hide

Help


See also1031058

Alignment palette


Stay On Top (Alignment Palette context menu)
Stay On Top 1031059

Choose Stay On Top  to keep this item in front of all other Delphi windows and dialog boxes.


Object Inspector context menu
Object Inspector context menu1031060

See also

The Object Inspector context menu provides you with commands for closing the Object Inspector, displaying Help, and for keeping the Object Inspector the topmost window.

The commands on the Object Inspector context menu are:

Revert To Inherited

Expand

Collapse

Stay On Top

Hide

Help


See also1031061

Object Inspector


Stay On Top (Object Inspector context menu)
Stay On Top (Object Inspector context menu)1031062

Choose Stay On Top from the Object Inspector context menu to keep the Object Inspector in front of all other Delphi windows and dialog boxes.


Expand (Object Inspector context menu);nested properties
Expand (Object Inspector context menu)1031063

Choose Expand from the Object Inspector context menu to view the nested properties of the selected property.

Properties with nested properties show a plus (+) sign on their left side in the Object Inspector. You need to view these nested properties to set them.


Collapse (Object Inspector context menu)
Collapse (Object Inspector context menu)1031064

Choose Collapse from the Object Inspector context menu to hide the nested properties of the selected property.

Properties with nested properties show a plus (+) sign on their left side in the Object Inspector. You need to view these nested properties to set them.


Breakpoint List context menu
Breakpoint List context menu1031065

See also

Use the Breakpoint List context menu to access commands that enable you to manipulate breakpoints.

The following commands appear on the Breakpoint List context menu:

Add	Opens the Edit Breakpoint dialog box, where you can create new breakpoints

Delete All	Removes all breakpoints

Disable All	Disables all enabled breakpoints

Enable All	Enables all disabled breakpoints

The following commands are available when you right-click on a defined breakpoint:

Enabled	Enables a disabled breakpoint

Delete	Removes a breakpoint

View Source	Locates a breakpoint in your source code quickly

Edit Source	Locates a breakpoint in your source code quickly and activates the Code Editor

Properties	Opens the Edit Breakpoint dialog box, where you can create new breakpoints

To display the Breakpoint List context menu:

Choose View|Breakpoints to display the Breakpoint List window, then do one of the following:

Right-click anywhere in the Breakpoint List window.

Press Alt+F10 when the Breakpoint List window is active.


See also1031066

Using breakpoints


Edit Breakpoint (Breakpoint List context menu)
Properties  (Breakpoint List context menu)1031067

See also	Breakpoint List context menu

Choose Properties from the Breakpoint List context menu to open the Edit Breakpoint dialog box, where you can create new breakpoints.

Alternate ways to perform this command are:

Choose Run|Add Breakpoint.

Choose Add Breakpoint from the Breakpoint List context menu.


See also1031068

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Add Breakpoint (Breakpoint List context menu)
Add (Breakpoint List context menu)1031069

See also	Breakpoint List context menu

Choose Add from the Breakpoint List context menu to open the Edit Breakpoint dialog box, where you can create new breakpoints.

Alternate ways to perform this command are:

Choose Run|Add Breakpoint.

Right-click an existing breakpoint in the Breakpoint List window and choose Properties from the Breakpoint List context menu.


See also1031070

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Delete Breakpoint (Breakpoint List context menu)
Delete (Breakpoint List context menu)1031071

See also	Breakpoint List context menu

Choose Delete from the Breakpoint List context menu to remove the selected breakpoint.

When you no longer need to examine the code at a breakpoint location, you can delete the breakpoint from the debugging session. This command is not reversible.


See also1031072

Delete All Using breakpoints (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Enable Breakpoint (Breakpoint List context menu)
Enabled (Breakpoint List context menu)1031073

See also	Breakpoint List context menu

Choose Enabled from the Breakpoint List context menu to toggle a breakpoint on or off. The breakpoint is enabled when the option is checked..

Disabling a breakpoint hides the breakpoint from the current program run. When you disable a breakpoint, its settings remain defined, but the breakpoint does not cause your program to stop. When you set a breakpoint, it is enabled by default.

Disabling is useful when you temporarily do not need a breakpoint but want to preserve its settings.


See also1031074

Enable All Using breakpoints (Breakpoint List context menu)

Disable Breakpoint (Breakpoint List context menu)

Disable All Using breakpoints (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


View Source (Breakpoint List context menu)
View Source (Breakpoint List context menu)1031075

See also	Breakpoint List context menu

Choose View Source from the Breakpoint List context menu to locate a breakpoint in your source code quickly.

The View Source command scrolls the Code Editor to the location of the breakpoint that is selected in the Breakpoint List window.


See also1031076

Edit Source (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Edit Source (Breakpoint List context menu)
Edit Source (Breakpoint List context menu)1031077

See also	Breakpoint List context menu

Choose Edit Source from the Breakpoint List context menu to locate a breakpoint in your source code quickly.

The Edit Source command scrolls the Code Editor to the location of the breakpoint that is selected in the Breakpoint List window, and activates the Code Editor.


See also1031078

View Source (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Disable All Breakpoints (Breakpoint List context menu)
Disable All (Breakpoint List context menu)1031079

See also	Breakpoint List context menu

Choose Disable All from the Breakpoint List context menu to disable all enabled breakpoints.

Disabling a breakpoint hides the breakpoint from the current program run. When you disable a breakpoint, its settings remain defined, but the breakpoint does not cause your program to stop. When you set a breakpoint, it is enabled by default.

Disabling is useful when you temporarily do not need a breakpoint but want to preserve its settings.


See also1031080

Disable Breakpoint (Breakpoint List context menu)

Enable Breakpoint (Breakpoint List context menu)

Enable All Using breakpoints (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Enable All Breakpoints (Breakpoint List context menu)
Enable All (Breakpoint List context menu)1031081

See also	Breakpoint List context menu

Choose Enable All to enable all disabled breakpoints.

Disabling a breakpoint hides the breakpoint from the current program run. When you disable a breakpoint, its settings remain defined, but the breakpoint does not cause your program to stop. When you set a breakpoint, it is enabled by default.

Disabling is useful when you temporarily do not need a breakpoint but want to preserve its settings.


See also1031082

Enable Breakpoint (Breakpoint List context menu)

Disable Breakpoint (Breakpoint List context menu)

Disable All Using breakpoints (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Delete All Breakpoints (Breakpoint List context menu)
Delete All (Breakpoint List context menu)1031083

See also	Breakpoint List context menu

Choose Delete All from the Breakpoint List context menu to remove all breakpoints.

When you no longer need to examine the code at a breakpoint location, you can delete the breakpoint from the debugging session. This command is not reversible.


See also1031084

Delete Breakpoint (Breakpoint List context menu)

Using breakpoints

The Breakpoint List window

The Delphi Debugger


Call Stack context menu
Call Stack context menu1031085

See also

Use the Call Stack context menu to access commands that enable you to examine previous function calls.

The commands on the Call Stack List context menu are:

View Source	Locates a function call in your source code quickly

Edit Source	Locates a function call in your source code quickly, and activates the Code Editor

To display the Call Stack context menu:

Choose View|Call Stack to display the Call Stack window, then do one of the following:

Right-click anywhere in the Call Stack window.

Press Alt+F10 when the Call Stack window is active.


See also1031086

Call Stack


View Source (Call Stack context menu)
View Source (Call Stack context menu)1031087

See also	Call Stack context menu

Choose View Source from the Call Stack context menu to locate a function call in your source code quickly.

The View Source command scrolls the Code Editor to the location of the function call that is selected in the Call Stack window.


See also1031088

Edit Source (Call Stack context menu)

Viewing function calls

The Delphi Debugger


Edit Source (Call Stack context menu)
Edit Source (Call Stack context menu)1031089

See also	Call Stack context menu

Choose Edit Source from the Call Stack context menu to locate a function call in your source code quickly.

The Edit Source command scrolls the Code Editor to the location of the function call that is selected in the Call Stack window, and makes the Code Editor active.


See also1031090

View Source (Call Stack context menu)

Viewing function calls

The Delphi Debugger


Watch List context menu
Watch List context menu1031091

See also

Use the Watch List context menu to access commands that enable you manipulate watch points.

The commands on the Watch List context menu are:

Edit Watch	Opens the Watch Properties dialog box, where you can create and modify watches

Add Watch	Opens the Watch Properties dialog box, where you can create and modify watches

Enable Watch	Enables a disabled watch expression

Disable Watch	Disables an enabled watch expression

Delete Watch	Removes a watch expression

Disable All Watching expressions	Enables all disabled watch expressions

Enable All Watching expressions	Disables all enabled watch expressions

Delete All Watching expressions	Removes all watch expressions

Stay on top	Keeps Watch List in front of all other Delphi windows and dialog boxes.

To display the Watch List context menu:

Choose View|Watches to display the Watch List window, then do one of the following:

Right-click anywhere in the Watch List window.

Press Alt+F10 when the Watch List window is active.


See also1031092

WatchList


Edit Watch (Watch List context menu)
Edit Watch (Watch List context menu)1031093

See also	Watch List context menu

Choose Edit Watch from the Watch List context menu to open the Watch Properties dialog box, where you can create and modify watches. After you create a watch, use the Watch List window to display and manage the current list of watches.

Alternate ways to perform this command are:

Choose Run|Add Watch.

Choose Add Watch At Cursor from the Code Editor context menu.

Right-click an existing watch in the Watch List window and choose Edit Watch from the Watch List context menu.


See also1031094

Watching expressions

The Watch List window

The Delphi Debugger


Add Watch (Watch List context menu)
Add Watch (Watch List context menu)1031095

See also	Watch List context menu

Choose Add Watch from the Watch List context menu to open the Watch Properties dialog box, where you can create and modify watches. After you create a watch, use the Watch List window to display and manage the current list of watches.

Alternate ways to perform this command are:

Choose Run|Add Watch.

Choose Add Watch At Cursor from the Code Editor context menu.

Choose Add Watch from the Watch List context menu.


See also1031096

Watching expressions

The Watch List window

The Delphi Debugger


Enable Watch (Watch List context menu)
Enable Watch (Watch List context menu)1031097

See also	Watch List context menu

Choose Enable Watch from the Watch List context menu to enable a disabled watch expression.

Disabling a watch hides the watch from the current program run. When you disable a watch, its settings remain defined, but Delphi does not evaluate the watch.

Disabling watches improves performance of the debugger because it does not monitor the watch as you step through or run your program. When you set a watch, it is enabled by default.


See also1031098

Enable All Watching expressions (Watch List context menu)

Disable Watch (Watch List context menu)

Disable All Watching expressions (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Disable Watch (Watch List context menu)
Disable Watch (Watch List context menu)1031099

See also	Watch List context menu

Choose Disable Watch from the Watch List context menu to disable an enabled watch expression.

Disabling a watch hides the watch from the current program run. When you disable a watch, its settings remain defined, but Delphi does not evaluate the watch.

Disabling watches improves performance of the debugger because it does not monitor the watch as you step through or run your program. When you set a watch, it is enabled by default.


See also1031100

Disable All Watching expressions (Watch List context menu)

Enable Watch (Watch List context menu)

Enable All Watching expressions (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Delete Watch (Watch List context menu)
Delete Watch (Watch List context menu)1031101

See also	Watch List context menu

Choose Delete Watch from the Watch List context menu to remove a watch expression.

When you no longer need to examine the value of an expression, you can delete the watch from the debugging session. This command is not reversible.


See also1031102

Delete All Watching expressions (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Enable All Watches (Watch List context menu)
Enable All Watches (Watch List context menu)1031103

See also	Watch List context menu

Choose Enable All Watches from the Watch List context menu to enable all disabled watch expressions.

Disabling a watch hides the watch from the current program run. When you disable a watch, its settings remain defined, but Delphi does not evaluate the watch.

Disabling watches improves performance of the debugger because it does not monitor the watch as you step through or run your program. When you set a watch, it is enabled by default.


See also1031104

Enable Watch (Watch List context menu)

Disable Watch (Watch List context menu)

Disable All Watching expressions (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Disable All Watches (Watch List context menu)
Disable All Watches (Watch List context menu)1031105

See also	Watch List context menu

Choose Disable All Watches from the Watch List context menu to disable all enabled watch expressions.

Disabling a watch hides the watch from the current program run. When you disable a watch, its settings remain defined, but Delphi does not evaluate the watch.

Disabling watches improves performance of the debugger because it does not monitor the watch as you step through or run your program. When you set a watch, it is enabled by default.


See also1031106

Disable Watch (Watch List context menu)

Enable Watch (Watch List context menu)

Enable All Watching expressions (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Delete All Watches (Watch List context menu)
Delete All Watches (Watch List context menu)1031107

See also	Watch List context menu

Choose Delete All Watches from the Watch List context menu to remove all watch expressions.

When you no longer need to examine the value of an expression, you can delete the watch from the debugging session. This command is not reversible.


See also1031108

Delete Watch (Watch List context menu)

Watching expressions

The Watch List window

The Delphi Debugger


Assign Local Data dialog box
Assign Local Data dialog box1031109

See Also

Copies the current set of records from a BDE dataset or client dataset to the selected client dataset. This is useful when populating client datasets for use as lookup tables, or when testing client datasets at design-time. Select the dataset you want to copy from the list of BDE datasets available to the current form, then click Ok.

To clear the records in a client dataset at design-time, make sure the dataset's Active property is set to True, then right-click the client dataset and choose Clear Data.


Project menu
Project menu1032001

See also

Use the Project menu commands to compile, or build your application. You must have a project open.

Add To Project	Add a file to a project

Remove From Project	Remove a file from a project

Import Type Library	Import a type library to a project.

Add To Repository	Add a project to the Object Repository

Compile	Compiles any source code that has changed since the last compile

Build All	Compiles everything in the project, regardless of whether source has changed

Syntax Check	Compiles your project but does not link it.

Information	Displays all the build information and build status for your project

Web Deployment Options	Make necessary settings to deploy a finished ActiveX control or ActiveForm to your web server.

Web Deploy	After setting the web deployment options and compiling your project, deploy your finished ActiveX control or ActiveForm.

Options	Displays the Project Options dialog box.


See also1032002

Compiling, building and running projects


Projet|Add to Project
Project | Add to Project 1032003

See also

Choose Project|Add to Project to open the Add To Project dialog box.

Add To Project dialog box

Use the Add To Project dialog box to add an existing unit and its associated form to the Delphi project. When you add a unit to a project, Delphi automatically adds that unit to the uses clause of the project file.

Look In	Select the drive or directory in which to look for files to add to the project. The File window displays the subdirectories of the current drive or directory, as well as all the files that match the filter specified in the Files of Type combo box.

File Window	Displays the subdirectories of the current directory as well as the files in the current directory that match the current filter. Select a file to add to the project by clicking with the mouse or using the arrow keys. Right-click on the files to bring up a context menu.

File Name	Enter the name of the file you want to add to the project, or a filter expression to limit the files that appear in the file window.

Files of Type	See "Look In" above.

Up One Level	Click this button to move up a level from the current directory.

Create New Folder	Click this button to create a new subdirectory in the current directory.

List	Click this button to display the files as a list of files with associated icons.

Details	Click this button to display files in a tabular format that includes detailed information about each file's size, type, time stamp, and other attributes.


See also1032004

Adding units and forms to a project

Viewing and manipulating a project's contents


Project|Remove From Project
Project | Remove From Project1032005

See also

Choose File|Remove From Project remove a unit from the current project.

Remove From Project dialog box

Use this dialog box to select one or more units to remove from the current project. When you select a unit and click OK, Delphi removes the selected unit from the uses clause of the current project file but does not delete the file from your disk. Any references to the unit that you added must be removed manually. Use the control or shift key to select more than one unit.

If you have modified the file during this editing session, Delphi prompts you to save your changes, to preserve the unit in another project. If you have not modified the file, Delphi removes that file from the project without prompting you.

Note:	Do not delete unit files by using other file management programs, or directly from the DOS prompt. Doing so will cause errors.


See also1032006

Removing forms and units from a project

Viewing and manipulating a project's contents


Import Type LIbrary
Project | Import Type Library1032007

See also

The Import Type Library dialog displays the type libraries registered on your system so you can add them to your Delphi projects. You can generate Pascal declarations in a .PAS file that let you use these types as though they were native VCL objects. In effect, the type library is placed within a Delphi wrapper.

The top part of the dialog is a list of type libraries that are currently registered and thus available to be imported into Delphi. This lists lets you extract the Pascal declarations from an existing control or free-standing type library. You can also conveniently register a new type library from this dialog box so that it is available to be imported.

To add and register a new type library:

1.	Click Add. The Register OLE Control dialog box appears.

2.	In the Register OLE Control dialog box, navigate to the disk or network location of the library file you want to add.

3.	Select the new type library. It is automatically registered on your system for Delphi and immediately appears in the list of available libraries in the Import Type Library dialog.

Add button 	The Add button lets you locate a new type library and register it in the Windows Registry, so that it will appear in the list of registered objects available to be imported into Delphi.

Remove button 	To remove a registered type library, click the Remove button. The library is removed from the Windows Registry and from this list.

Class names 	Shows only the control classes in the selected library.

Unit dir name 	Shows the name of the directory that will contain the unit using this library. Only the path root is shown; no file name appears. The unit name is derived from the internal type library name. Click the Browse button to move up the directory tree.


See also1032008

An overview of OLE technologies

Working with type libraries

Type Library editor

About type libraries

When to use a type library

Type Library deployment

Valid types

Creating a new type library

Adding an interface to the type library

Adding properties and methods to the type library

Adding a component object class to the type library

Adding an enumeration to the type library

Saving and registering type library information


Add To Repository
Project | Add To Repository1032009

See also

Choose Project|Add To Repository to open the Add to Repository  dialog box. Use this command to add a project to the Object Repository.

You can add your own projects and forms to those already available in the Object Repository. This is helpful in situations where you want to enforce a standard framework for programming projects throughout an organization.

Add to Repository dialog box

Use this dialog to save a project template to the Object Repository. After saving an application as a template, use the Edit Object Info dialog to edit the description, delete the template, or change the icon.

Title	Enter the name of the template. The maximum length for a title is 40 characters.

Description	Enter a description of the template. The description appears under the template name in the Select Template dialog. The maximum length for a description is 255 characters.

Page	From the drop-down list box, choose the name of the page (probably Projects) in the Repository that you want the template to appear on.

Author	Enter text identifying the author of the application. Author information appears only when you select View Details form the speed menu.

Template Icon	Click the Browse button to open the Select Icon dialog.


See also1032010

Using Project Templates


Project|Compile
Project | Compile1032011

See also

Use Project|Compile to compile all files in the current project that have changed since the last build into a new executable file (.EXE).

This option is identical to Project|Build All, except that it builds only those files that have changed.

If you have selected Show Compiler Progress from the Preferences page of the Tools|Environment Options dialog box, the Compiling dialog box displays information about the compilation progress and results. When your application successfully compiles, choose OK to close the Compiling dialog box.

If the compiler encounters an error, Delphi reports that error on the status line of the Code Editor and places the cursor on the line of source code containing the error.

The compiler builds .EXE files according to the following rules:

The project (.DPR) file is always recompiled.

If the source code of a unit has changed since the last time the unit was compiled, the unit is compiled. When a unit is compiled, Delphi creates a file with a .DCU extension for that unit.

If Delphi cannot locate the source code for a unit, that unit is not recompiled.

If the interface part of a unit has changed, all the other units that depend on the changed unit are recompiled.

If a unit links in an .OBJ file (external routines), and the .OBJ file has changed, the unit is recompiled.

If a unit contains an Include file. and the Include file has changed, the unit is recompiled.

You may choose to compile only portions of your code if you use conditional directives and predefined symbols in your code.


Project|Build All
Project | Build All1032012

See also

Choose Project|Build All to rebuild all the components of your application regardless of whether they have changed.

This option is identical to Project|Compile, except that it rebuilds everything.

The Project|Build All command recompiles all files included in the project file.


Project|Syntax Check
Project | Syntax Check1032013

Choose Project|Syntax Check to compile the modules of your project but not link them. This provides you with a means for checking your code for compile time errors.

If you do not have a project open when you choose this command, only the current module will compile.

Using Project|Syntax Check is faster than using Project|Compile because Delphi does not have to create the object code for the units.


Project|Information
Project | Information1032014

Choose Project|Information to open the Information dialog box.

Information dialog box

Use this dialog box to view the program compilation information and compilation status for your project.

Program Information

The Program Information options provide you with information about your project.

Options	What it lists

Source Compiled	Total number of lines compiled

Code Size	Total size of the executable or DLL without debug information

Data Size	Memory needed to store the global variables

Initial Stack Size	Memory needed to store the local variables

File size	Size of final output file.

Status Information

The Status Information line displays whether or not your last compile succeeded or failed.


Project|Web Deployment Options
Project | Web Deployment Options1032015

Choose Project| Web Deployment Options to configure a finished ActiveX control or ActiveForm for deployment to your web server.  You should first set web deployment options then compile the project. Then you may choose Project|Web Deploy to deploy the current open ActiveX project.

See Instructions on deploying ActiveX controls or ActiveForms on the Web

Default checkbox	If checked, saves the current settings from the dialog box�s Project, Packages, Additional Files, and Code Signing pages as the default options. To restore Delphi�s original default settings, delete or rename the DEFPROJ.DOF file.

The Web Deployment Options dialog box contains four tabbed pages of settings:

Project page	Specifies locations of files and the URL.  Also, configuration settings for CAB compression.

Packages Page	Specifies packages used by this project

Additional Files Page	Specifies other files associated with this project.

Code Signing Page	Lets end user view information on author of the control and whether the code has been modified since it was signed by the author.


Project Page1032016

The options on the project page apply to the .OCX file or .CAB file containing the OCX and become the default options for any packages and additional files deployed with the project. You can set the file locations, URL, and other deployment options for the project.

Note:	These are paths only, not complete file names.

Directory/URL Options	Meaning

Target Dir	Location as a path of the ActiveForm.OCX on the web server, either a standard or a UNC path

Target URL	Location as a URL of the ActiveForm.OCX on the web server

HTML Dir	Location as a path of the HTML file that contains a reference to the ActiveForm, either a standard or a UNC path

You can deploy the .OCX and any packages and additional files as cabinet files.  A cabinet is a single file, usually with a .CAB file extension, that stores compressed files in a file library. Cabinet compression can decrease a file�s download time up to 70%. Each file that you deploy can be .CAB file compressed.

A compressed file can be spread over several cabinet files. During installation, the setup application decompresses the files stored in a cabinet and copies them to the user's system.

General Options	Meaning

Use CAB file compression	Compress the OCX, and required packages and additional files, unless specified otherwise

Include file version number	Include version number contained in Project|Options VersionInfo

Autoincrement release number	Automatically increment the projects release number contained in Project|Options VersionInfo

Code sign project	Code sign the .OCX or .CAB file containing the OCX, and unless specified otherwise, any DLLs or additional files to deploy.

Deploy required packages	If checked, any required packages will be deployed with the project.

Deploy additional files	If checked, any additional files specified on the Addition Files page will be deployed with the project.


Packages Page1032017

When deploying your ActiveForm or ActiveX control, you have the option of specifying individual deployment options for each required package file used by the project as part of your deployment. Each of these packages can be code signed and put into .CAB files. Packages that ship with Delphi are already code signed with the Borland signature.

To modify the settings for a particular package, select the package in the �Packages used by project� list box, and modify the settings as needed.

CAB Options	Meaning

Compress in separate CAB	If checked, create a separate .CAB file for the package. This is the default.

Compress in project CAB	If checked, include the package in the project .CAB file

Output Options	Meaning

Use file VersionInfo	If checked, this option takes the version info from the resource in the package file and enters it into the.INF file for the project.

Code sign file	If checked, Code sign the package or .CAB file containing the package.

Directory/URL Options	Meaning

Target URL	Location as a Uniform Resource Locator (URL) of the package on your Web Server. If left blank, the Web browser will assume the file exists on the target machine. If the package is not found on the target machine, the download of the OCX will fail.

Target directory	Location as a path of the package on the Web server. This can be a standard path name or a UNC path.


Additional Files Page1032018

Specifies other files associated with this project.

If the ActiveForm or ActiveX control is deployed with any packages and/or additional files, an .INF file is automatically created. This file specifies various files that must be downloaded and setup for the OCX to run. The syntax of the .INF file allows URLs pointing to files to download, and platform independence (by enumerating files for various platforms).

CAB Options	Meaning

Compress in separate CAB	If checked, create a separate .CAB file for the file. This is the default.

Compress in project CAB	If checked, include the file in the project .CAB file.

Output Options	Meaning

Use file VersionInfo	If checked, If the file contains VersonInfo resources, takes the version info from the resource in the file and enters it into the.INF file for the project.

Code sign file	If checked, code sign the file or .CAB file containing the file.

Directory/URL Options	Meaning

Target URL	Location as a Uniform Resource Locator (URL) of the file on your Web Server. If left blank, the Web browser will assume the file exists on the target machine. If the file is not found on the target machine, the download of the OCX will fail.

Target directory	Location as a path of the file on the Web server. This can be a standard path name or a UNC path. Leave blank to assume the file exists and ensure that it won�t be overwritten.


Code Signing Page1032019

Code signing allows the user of the control to determine with certainty who wrote the control and that the code has not been modified since it was signed. Each file that you deploy can be code signed. Signing data does not alter it. Code signing generates a digital signature string that is added to the file.

The Code Signing page contains settings used when creating a digital signature. To create a digital signature, a hash value (also known as a message digest) is first created using the selected Cryptographic digest algorithm. This hash value is then signed, using the Private key. To obtain the private key and credentials certificate files, contact Microsoft.

Required information	Meaning

Credentials file	To obtain this certification file, contact Microsoft.

Private key	The private key is known only to its owner.  It is used to generate the digital signature. To obtain this file, contact Microsoft

Optional information	Meaning

Name of the application	Application name as you would like it to appear in the digital certificate displayed by the Web browser.

Application or company URL	An URL that provides a link to a web page for the product or company.

Cryptographic digest algorithm	Meaning

MD5	The MD5 hashing algorithm was developed by RSA Data Security, Inc and is commonly supported by most browsers. This algorithm generates 128-bit hash value. DEFAULT.

SHA 1	The SHA hashing algorithm was developed by the National Institute of Standards and Technology (NIST) and by the National Security Agency (NSA). This algorithm generates a 160-bit hash value.


Project|Web Deploy
Project | Web Deploy1032020

Choose Project|Web Deploy to deploy a finished ActiveX control or ActiveForm to your web server. You would use this command only after setting the Web Deployment Options and then compiling your project.

The ActiveX library (.OCX) is placed in the target directory specified in the Web deployment options. An HTML file (.HTM) that contains a URL reference to the ActiveX library in the target directory is created in the HTML directory specified in the Web Deployment options. When this HTML file is viewed in a Web browser, your ActiveX control or ActiveForm runs as an embedded application within the browser.

See Instructions on deploying ActiveX controls or ActiveForms on the Web


Project|Options
Project | Options1032021

Choose Project|Options to display the Project Options dialog box. Use the pages of this dialog box to specify form, application, compiler, and linker options for your project, and to manage project directories.

The pages of the Project Options dialog box are:

Forms

Application

Compiler

Linker

Directories/Conditionals

VersionInfo

Packages

To change pages in the dialog box:

Click the tab that represents the page you want to use.

To save the current project options as defaults:

Check Default and click OK.

Default	Check Default to save the current project options so that every new project you create will use those options.


Project|Options - Forms
Forms (Project | Options)1032022

Use the Forms page of the Project Options dialog box to select the main form for your applications and to choose which of the available forms are automatically created and in which order.

Main Form	Displays the form users will see when they start your application. Use the drop-down list to select which form is the main form for the project. The main form is the first form listed in the Auto-Create Forms list box.

Auto-Create Forms	Lists those forms that are automatically added to the startup code of the project file and created at run time. You can rearrange the create order of forms by dragging and dropping forms to a new location. To select multiple forms, hold down the Shift key while selecting the form names.

Available Forms	Lists those forms that are used by your application but are not automatically created. If you want to create an instance of one of these forms, you must call the its Create method.

Default	Check Default to save the current project options so that every new project you create will use those options.

Arrow buttons	Use the arrow buttons to move one or more files or all the files from one list box to the other.

To move all the files from one list box into the other:

Click the double arrow buttons ( >> or << ).

Drag and drop the files from one list box into the other.

To move only the selected file or files from one list box into the other:

Click the single arrow buttons ( > or < ).

Drag and drop the file from one list box into the other.


Project|Options - Application
Application (Project | Options)1032023

See also

Use the Application page of the Project Options dialog box to specify a title, a Help file, an icon, and an extension for your application.

Application Settings

Title	Specify a title to appear under the application's icon when the application is minimized. The character limit is 255 characters.

Help File	Specify the name of the Help file (.HLP) your application will use whenever your application calls Help. The Help file name is passed to the WinHelp function call.  If you are unsure of the Help file name, you can click the Browse button to display the Application Help File dialog box.

Icon	Displays the icon file (.ICO) that will represent the application in the Program Manager and when the application is minimized.  To change the icon, click Load Icon and Delphi displays the Application Icon dialog box, where you can select an icon.

Output Setting

Target file extension	Specify the file extension to be used for the target executable file. If the project is  an ActiveX application or DLL the standard file extension can be specified, such as .ocx for an ActiveX file.

Default	Check Default to save the current project options so that every new project you create will use those options.


See also1032024

Specifying a form as the project main form

Application page (Project Options)

Application Icon dialog box


Application Icon dialog box
Application Icon dialog box1032025

Use the Application Icon dialog box to select an icon that will represent your application in the Program Manager and when your application is minimized.

To display this dialog box:

Select Project | Options, select the Application page, click Load Icon.

File Name	Enter the name of the file you want to use, or enter or wildcards to use as filters in the Files window.

Files	Displays subdirectories of the current directory as well as all files in the current directory that match the filter in the File Name edit box or the file type in the Files Of Type combo box. Select an icon file for your application's icon using the mouse or arrow keys. Right-click on a file to bring up a context menu.

Files Of Type	Choose the type of file you want to use; the default file type is an icon (.ICO). All files in the current directory of the selected type appear in the Files list box.

Look In	Select the drive or directory in which to look for the icon file. The Files window displays the subdirectories of the current drive or directory as well as all files that match the current filter.


Application Help File dialog box
Application Help File dialog box1032026

Use the Application Help File dialog box to select a Help file to use as the Help file for your application. The Help file you specify here is entered into the Help File edit box on the Applicaton page of the Project Options dialog box.

To display this dialog box:

Select Project | Options, select the Application page and click Browse

File Name	Enter the name of the file you want to use, or enter or wildcards to use as filters in the Files window.

Files Window	Displays all subdirectories in the current directory as well as files in the current directory that match the filter in the File Name edit box or the file type in the Files Of Type combo box. Select a Help file for your application using the mouse or arrow keys. Right-click on a file to bring up a context menu.

Files Of Type	Choose the type of file you want to use; the default file type is a Help file (.HLP). All files in the current directory of the selected type appear in the Files list box.

Look In	Select the drive or directory in which to look for the Help file. The Files window displays the subdirectories of the current drive or directory as well as all files that match the current filter.


Project|Options - Compiler
Compiler (Project | Options)1032027

See also

Use the Compiler page of the Project Options dialog box to set options for how you want your program to compile. These options correspond to switch directives that you can also set directly in your program code.

Selecting an option is equivalent to setting the switch directive to its positive (+) state.

Code generation	Effect

Optimizations	Enables compiler optimizations.  Corresponds to {$O}.

Aligned record fields	Aligns elements in structures to 32-bit boundaries. Corresponds to {$A}.

Stack frames	Forces compiler to generate stack frames on all procedures and functions. Corresponds to {$W}.

Pentium-Safe FDIV	Generates code that detects a faulty floating-point division instruction. Corresponds to {$U}.

Runtime errors	Effect

Range Checking	Checks that array and string subscripts are within bounds. Corresponds to {$R}.

I/O Checking	Checks for I/O errors after every I/O call. Corresponds to {$I}.

Overflow Checking	Checks overflow for integer operations. Corresponds to {$Q}.

Syntax options	Effect

Strict Var-Strings 	Sets up string parameter error checking. Corresponds to {$V}. (If the Open parameters option is selected, this option is not applicable.)

Complete Boolean Eval 	Evaluates every piece of an expression in Boolean terms, regardless of whether the result of an operand evaluates as false. Corresponds to {$B}.

Extended Syntax 	Enables you to define a function call as a procedure and to ignore the function result. Also enables Pchar support. Corresponds to {$X}.

Typed @ Operator 	Controls the type of pointer returned by the @ operator. Corresponds to {$T}.

Open Parameters 	Enables open string parameters in procedure and function declarations. Corresponds to {$P}. Open parameters are generally safer, and more efficient.

Huge Strings	Enables new garbage collected strings.  The string keyword corresponds to the new AnsiString type with this option enabled.   Otherwise the string keyword corresponds to the ShortString type. Corresponds to {$H}.

Assignable Typed Constants	Enable this for backward compatability with Delphi 1.0.  When enabled, the compiler allows assignments to typed constants.  Corresponds to {$J}

Debugging	Effect

Debug Information 	Puts debug information into the unit (.DCU) file. Corresponds to {$D}.

Local Symbols 	Generates local symbol information. Corresponds to {$L}..

Symbol Information 	Generates symbol information. Corresponds to {$Y}.

Messages	Effect

Show Hints 	Causes the compiler to generate hint messages.

Show Warnings 	Causes the compiler to generate warning messages.

Assertions 	Generates code for assertions placed in code. Corresponds to {$C}..

Default check box

Check Default to save the current project options so that every new project you create will use those options.


See also1032028

Compiler directives


Project|Options - Linker
Linker (Project | Options)1032029

See also

Use the Linker page of the Project Options dialog box to specify how your program files are linked.

Map file

Select the type of map file produced, if any. The map file is placed in the Output Directory specified on the Directories/Conditionals page, and it has a .MAP extension.

Option	Effect

Off	Does not produce map file.

Segments	Linker produces a map file that includes a list of segments, the program start address, and any warning or error messages produced during the link.

Publics	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, and a list of alphabetically sorted public symbols.

Detailed	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, a list of alphabetically sorted public symbols, and an additional detailed segment map. The detailed segment map includes the segment address, length in bytes, segment name, group, and module information.

Linker output

Specify the output from the linker.

Option	Effect

Generate DCUs	Output standard Delphi DCU format files

Generate Object

Files	Output binary Object files (OBJ)

EXE and DLL Options

Check box	What it does

Generate Console Application	Causes linker to set a flag in the application�s .EXE file indicating a console mode application.

Include TD32 Debug Info	Places debug information in your program's executable file. This will make the resulting .EXE file larger, but it does not affect memory requirements or performance.

Use this option only if you are using an external debugger. Use of this option causes an increase in the length of time required to compile a project.

Memory sizes

Use these edit boxes to specify the minimum and maximum stack size and heap image base for the compiled executable. Memory-size settings can also be specified in your source code with the $M compiler directive.

Option	Specifies

Min Stack Size	Initial commited size of the stack..

Max Stack Size	Total reserved size of the stack.

Image Base	Specifies the preferred load address of the compiled image.  This value is typically only changed when compiling to a DLL.

Description

EXE Descriptor

This field can contain a string of up to 255 characters.  The string will be linked to $D and included in the executable file.  It is most often used to insert copyright information into the application. Copyright information can also be included as part of the VersionInfoMOptionsVersionInfo file.

Default

Check Default to save the current project options so that every new project you create will use those options.


See also1032030

Compiler directives


Project|Options - Directories/Conditionals
Directories/Conditionals (Project | Options)1032031

See also

Use the Directories/ Conditionals page of the Project Options dialog box to specify the location of files needed to compile, link, and distribute your program. Click the down arrow next to any edit box to choose from a list of previously entered directories or symbols.

Directories

Output Directory	Where the compiler should put the compiled units and the executable file.

Unit Output Directory	Specifies a separate directory to contain the .dcu files. Note, .DCP files can be relocated by setting the DCP output directory path on the library page of the Tools | Environment Options dialog box.

Search Path	The location of your source files.  Only those files on the compiler's search path or the library search path will be included in the build. If you try to build your project with a file not on the search path, you will receive a compiler error.  You must include the entire search path.

Guidelines for search paths

Use the following guidelines when entering directory names into the Search Path edit box:

Separate multiple directory path names with a semicolon (;).

Whitespace before and after the semicolon is allowed but not required.

You can use a maximum of 127 (note that this may change...) characters (including whitespace).

Relative and absolute path names are allowed, including path names relative to the logged position in drives other than the current one.

Debug source path	Search path for the debugger.  The debugger searches paths defined by the compiler by default. If the directory structure has changed since the last compile, a path can be entered here to include a file in the debugging session.

Conditional Defines	Symbols referenced in conditional compiler directives. You can separate multiple defines with semicolons.

Unit Aliases	Useful for backwards compatibility.  Specify alias names for units that may have changed names or were merged into a single unit.  The format is <oldunit>=<newunit>.  You can separate multiple aliases with semicolons.  The default value is WinTypes=Windows;WinProcs=Windows.Default

Default	Check to save the current project options so that every new project you create will use those options.


See also1032032

Compiling, building, and running projects

Managing projects


VersionInfo (Project | Options)
VersionInfo (Project | Options)1032033

Use this page to enable the version information option and to specify version information for the project.

Include version information in project	When enabled, version information can be entered and will be included in the compiled code. When version information is included, if a user right-clicks the program icon and selects properties version information is displayed.

Module Version Number	Major, Minor, Release, and Build each specify an unsigned  integer between 0 and 65,535.  The combined string defines a version number for the application.

Auto-increment build number	If enabled, the build number will be incremented each time the project is compiled.

Module Attributes

Module attributes are flags that can be included in the version information for informational use only.  If a project is compiled in debug mode, the debug flag will be included in the version information.  Each of the remaining flags can be selected as needed.

Attribute	Effect

Debug Build	Included to indicate that the project was compiled in debug mode.

Pre-Release	Include to indicate the version is not the commercially released product.

Special Build	Include to indicate that the version is a variation of the standard release.

Private Build	Include to indicate that the version was not built using standard release procedures.

DLL	Include to indicate that the project includes a dynamic-link library.

Key/Value

A default set of keys are included.

Key	Value indicates

CompanyName	The company that produced the file. Required.

FileDescription	File description. You can display this string in a list box during installation. Required

FileVersion	File version number. Required.

InternalName	File internal name. If file does not have internal name, use original filename, without extension. Required.

LegalCopyright	File copyright notices. Optional.

LegalTrademarks	Trademarks and registered trademarks that apply to file. Optional.

OriginalFilename	Original file name, not including path. Required.

ProductName	Name of product that file is distributed with. Required.

ProductVersion	Version of product that file is distributed with. Required.

Comments	Additional information for diagnostic purposes. Optional.

To edit key entries, select the key and re-enter the name.

To add key entries, right-click within the Key/Value table and select Add Key.

Language ID

The language ID indicates which Code Page the users system will require to run the application, that is, it indicates which language the application displays. The following languages are supported.

Constant	Language	Constant	Language

0x0401	Arabic	0x0415	Polish

0x0402	Bulgarian	0x0416	Brazilian Portuguese

0x0403	Catalan	0x0417	Rhaeto-Romanic

0x0404	Traditional Chinese	0x0418	Romanian

0x0405	Czech	0x0419	Russian

0x0406	Danish	0x041A	Croato-Serbian (Latin)

0x0407	German	0x041B	Slovak

0x0408	Greek	0x041C	Albanian

0x0409	U.S. English	0x041D	Swedish

0x040A	Castilian Spanish	0x041E	Thai

0x040B	Finnish	0x041F	Turkish

0x040C	French	0x0420	Urdu

0x040D	Hebrew	0x0421	Bahasa

0x040E	Hungarian	0x0804	Simplified Chinese

0x040F	Icelandic	0x0807	Swiss German

0x0410	Italian	0x0809	U.K. English

0x0411	Japanese	0x080A	Mexican Spanish

0x0412	Korean	0x080C	Belgian French

0x0413	Dutch	0x0C0C	Canadian French

0x0414	Norwegian - Bokml	0x100C	Swiss French

0x0810	Swiss Italian	0x0816	Portuguese

0x0813	Belgian Dutch	0x081A	Serbo-Croatian (Cyrillic)

0x0814	Norwegian - Nynorsk


Project|Options - Packages
Packages page (Project | Options, Component | Install packages)1032034

See also

Use this page to specify the design-time packages installed in the IDE and the runtime packages required by your project.

Design Packages

A list of the design time packages available to the IDE. Items with a check mark are installed in the current project. When a package is installed, it may register components that appear on the Component palette, experts that appear on the menu bar and New Items (File | New) dialog, and property editors for custom components.

Exercise caution when uninstalling packages, whether by using the Remove button or by unchecking the package's check box. When a package is removed, any components registered by it become unavailable in the IDE. If a project contains forms that use unavailable components, you will not be able to load the forms; if this happens, reinstall the package and reload the unit.

The following buttons manipulate entries in the list.

Button	Description

Add	Installs a design time package. The package will be available in all projects.

Remove	Deletes the selected package. The package will become unavailable in all projects.

Edit	Opens the selected package in the Package editor if source code is available.

Components	Displays a list of the components included in the selected package.

As packages are installed and uninstalled, you may notice that the runtime package list is updated. Delphi automatically adds runtime packages that are required by installed design-time packages.

Runtime Packages

Check Build With Runtime Packages to use run-time packages when the executable file is created. Enter a list of packages to use as run-time packages, separated by semicolons (VCL30;VCLDB30;VCLDBX30), into the edit box or click Add and specify a package to add to the list.

When a package is used by a project, Delphi must find the package's .DCP file in order to compile. When Delphi cannot find the .DCP, it is often because the .DCP's directory is not included in the global Library Search Path. (To edit the Library Search Path, choose Tools | Environment Options and select the Library tab.)

Default

Check the "Default" check box in the lower left corner of the dialog to turn the current package configuration into the default configuration for all new projects.


See also1032035

Compiling, building, and running projects

Managing projects


New Package
New Package1032036

See Also

Use the New Package dialog box to specify the file name and description of a new package. Click OK to display the new package in the Package editor.

File Name

Enter the name of the package to create. You can include a directory path with the name; otherwise, the package will reside in the current directory. To open a file/directory selection dialog box, click Browse. If you type a file name directly in the New Package dialog box, the .DPK extension will be added automatically.

Package names must be unique within a project. If you name a package �STATS�, the Package editor generates a source file for it called �STATS.DPK�; the compiler generates an executable and a binary image called �STATS.DPL� and �STATS.DCP�, respectively. Use �STATS� to refer to the package in the requires clause of another package, or when using the package in an application.

Description

A brief description that appears in the Project Options dialog when the package is installed.


Into New Package
Into new package1032037

See Also

Specify the file name and description of a new package. Click OK to display the new package in the Package editor. Delphi adds the component to the package and builds the package.

File Name

Enter the name of the package to create. You can include a directory path with the name; otherwise, the package will reside in the current directory. To open a file/directory selection dialog box, click Browse. If you type a file name directly in the New Package dialog box, the .DPK extension will be added automatically.

Package names must be unique within a project. If you name a package �STATS�, the Package editor generates a source file for it called �STATS.DPK�; the compiler generates an executable and a binary image called �STATS.DPL� and �STATS.DCP�, respectively. Use �STATS� to refer to the package in the requires clause of another package, or when using the package in an application.

Description

A brief description that appears when the package is installed.


Into existing package
Into existing package1032038

See Also

Specify the file name of the package to install into, then click OK to display the package in the Package editor. Delphi adds the component to the package and rebuilds the package if necessary.

File Name	Use the drop-down list to select the name of an installed package, or enter the name of another existing package.

Description	A brief description of the selected package.


Add Design Package
Add Design Package1032039

See Also

Use the Add Design Package dialog box to specify the name of a design time package to add to the Design packages list. This is a standard Windows Open dialog.


Add Runtime Package
Add Runtime Package1032040

See Also

Use the Add Runtime Package dialog box to specify the name of a runtime package to add to the Design packages list.

Package Name	Type the name of the package to add to the Runtime Packages list,or click the Browse button to search for the package using the Package File Name dialog. If the package is in the Search Path, a full path name is not required. (If the package directory is not in the Search Path, it will be added at the end.)

Search Path	If you haven't included a full directory path in the Package Name edit box (see above), make sure the directory where your package resides is in this list. If you add a directory in the Search Path edit box, you will be changing the global Library Search Path for Delphi.


See Also1032041

About packages


Close this dialog box and open package?1032042

When editing a package selected in the Design packages list, Delphi closes the Project Options dialog box and displays the selected package in the package editor. Click Yes to edit the package or No to return to the Project Options dialog box.


Another file with the same base name <file> is already on the search path1032043

This error message appears when a file is found on the search path but not at the location specified by the user when creating a new component, installing a component, importing an ActiveX control, or adding a required package to a package. Because the Library Search Path is used to locate files when building a package, this conflict prevents the compiler from finding the intended file.

The problem can be solved by modifying the Search Path so that the directory of the intended file precedes the directory of the conflicting file.


Package package will be built then installed. Continue?1032044

This message appears when adding a component or ActiveX control to a package. Click Yes to rebuild the package to reflect the new component or control.


Package(s) <package list> will also be uninstalled because they require package <package name>. Continue uninstall?1032045

Appears when installed packages rely on packages that you�re trying to uninstall. Click Yes to uninstall the dependent packages.


Components1032046

See Also

Lists components in the selected package, along with the icons for those components that appear on the Component palette if the package is installed.


Package editor
Package editor1032047

See Also

The Package editor lists the units in a package, and the other packages it requires. You can save your changes with File|Save or Save As.

Contains page	The Contains page lists the units included in the package. To add a unit to the package, click the Add button. To edit a unit's source code, double-click it.

Requires page	The Requires page lists the other packages required by the current package. To add a package, click Add.  To display a package in its own Package editor, double-click it.

Package editor SpeedBar

Button	Description

Compile	Compiles the current package. If changes to the package are required, a dialog box appears that lists the changes that will be made to the package before it is compiled.

Add	Adds an item (see the Contains page and Requires page for details).

Remove	Removes the selected item from the package.

Options	Displays the Package Options Dialog Box.

Install	Installs the current package as a design time package. If changes to the package are required, a dialog box appears that lists the changes that will be made to the package before it is compiled.

Update	Updates the Package editor to reflect changes made in the .DPK file. This button is enabled when the .DPK file has been modified using the Code editor; as an additional indication that the .DPK file has been modified, entries in the Package editor appear grayed.

Package editor context menu1032048

To display the Package editor context menu, right-click an item within either Package editor page.

Command	Description

Save Package	Saves the current package

Compile	Equivalent to Compile button on SpeedBar

Build All	Builds all items in the package, whether or not they have changed

Add Unit	Equivalent to Add button on SpeedBar

Remove Unit	Equivalent to Remove button on SpeedBar

Add Required Package	Equivalent to Add button on SpeedBar

Remove Required Package	Equivalent to Remove button on SpeedBar

View Unit	Lets you view the selected unit�s source code

View Required Package	Lets you view the selected package in a new Package editor

View Package Source	Lets you view the package source code (.DPK file)

(View | Toggle Form/Unit can also be used to switch between the Package and Code editors.)

Options	Equivalent to Options button on SpeedBar

Install	Equivalent to Install button on SpeedBar

Update	Equivalent to Update button on SpeedBar


Add Unit
Add Unit1032049

Enter the name of the unit file to add in Unit File Name (or select it using Browse). If you enter a name, Delphi searches the paths specified in Search path.

Unit File Name	The name of the unit to add. If the unit is in the Search Path, a full path name is not required. If the unit directory is not in the Search Path, it will be added to the end.

Search Path	If you haven't included a full directory path in the Unit File Name edit box (see above), make sure the directory where the unit resides is in this list. If you add a directory in the Search Path edit box, you will be changing the global Library Search Path for Delphi.


Add Package
Add Package1032050

Enter the name of the package to add in Package name (or select it using Browse). If you enter a name, Delphi searches the paths specified in Search path.

Package Name	Enter the name of the package to add. If the package is in the Search Path, a full path name is not required. (If the package directory is not in the Search Path, it will be added to the end.)

Search Path	If you haven't included a full directory path in the Package Name edit box (see above), make sure the directory where your package resides is in this list. If you add a directory in the Search Path edit box, you will be changing the global Library Search Path for Delphi.

When a package is required by another package, Delphi must find the package's .DCP file in order to compile.


See Also1032051

Package Collection editor

About packages


Package Options dialog box
Package Options dialog box1032052

See Also

The Package Options dialog box lets you specify compiler options for the current package. The pages of the Project Options dialog box are:

Description

Compiler

Linker

Conditionals

VersionInfo

Global

To change pages in the dialog box:

Click the tab at the top of the dialog box that represents the page you want to use.


See Also1032053

About packages


Description page
Description page (Package Options dialog box)1032054

See Also

The Description page lets you specify a description for the package, the uses of the package, and how the package is built.

Description	A brief description that appears when the package is installed.

Usage options	Check Design Package if you want the package to be installable on the Component palette.

Check Runtime Package if you want the package to be deployable with an application.

Check both Design Package and Runtime Package if you want the package to be both installable and deployable.

If neither Design Package nor Runtime Package is checked, the package cannot be installed on the Component palette or deployed with applications. Use this option for packages that exist only to be referenced (required) by other (design-time) packages.

If your package uses custom property editors, it's a good idea to compile separate design-time and runtime versions of it. The deployed runtime package will be smaller than the design-time version, since it won't contain code for the property editors.

Build control	If the package is low-level and does not change often, click Explicit Rebuild.  It is built only when you display it in the Package editor and click Build. For automatic compilation, click Rebuild As Needed.


See Also1032055

Package Options dialog box

About packages


Compiler page
Compiler page (Package Options dialog box)1032056

See Also

Use the Compiler page to set options for how you want your package to compile. These options correspond to switch directives that you can also set directly in your package code.

Selecting an option is equivalent to setting the switch directive to its positive (+) state.

Code generation	Effect

Optimizations	Enables compiler optimizations.  Corresponds to {$O}.

Aligned record fields	Aligns elements in structures to 32-bit boundaries. Corresponds to {$A}.

Pentium-Safe FDIV	Generates code that detects a faulty floating-point division instruction. Corresponds to {$U}.

Stack frames	Forces compiler to generate stack frames on all procedures and functions. Corresponds to {$W}.

Runtime errors	Effect

Range Checking	Checks that array and string subscripts are within bounds. Corresponds to {$R}.

I/O Checking	Checks for I/O errors after every I/O call. Corresponds to {$I}.

Overflow Checking	Checks overflow for integer operations. Corresponds to {$Q}.

Syntax options	Effect

Strict Var-Strings 	Sets up string parameter error checking. Corresponds to {$V}. (If the Open parameters option is selected, this option is not applicable.)

Complete Boolean Eval 	Evaluates every piece of an expression in Boolean terms, regardless of whether the result of an operand evaluates as false. Corresponds to {$B}

Extended Syntax 	Enables you to define a function call as a procedure and to ignore the function result. Also enables Pchar support. Corresponds to {$X}.

Typed @ Operator 	Controls the type of pointer returned by the @ operator. Corresponds to {$T}

Open Parameters 	Enables open string parameters in procedure and function declarations. Corresponds to {$P}. Open parameters are generally safer, and more efficient.

Huge Strings	Enables garbage collected strings.  The string keyword corresponds to the new AnsiString type with this option enabled.   Otherwise the string keyword corresponds to the ShortString type. Corresponds to {$H}.

Assignable Typed Constants	Enable this for backward compatability with Delphi 1.0.  When enabled, the compiler allows assignments to typed constants.  Corresponds to {$J}.

Debugging	Effect

Debug Information	Puts debug information into the unit (.DCU) file. Corresponds to {$D}.

Local Symbols	Generates local symbol information. Corresponds to {$L}..

Symbol Information	Generates symbol cross-reference information. Corresponds to {$Y}.


See Also1032057

Package Options dialog box

About packages


Linker page
Linker page (Package Options dialog box)1032058

See Also

Use the Linker page of the Package Options dialog box to specify how your program files are linked.

Memory sizes

Use this edit box to specify the heap image base for the compiled executable. You can also specify memory-size settings in your source code by using the $M compiler directive.

Option	Specifies

Image Base	Specifies the preferred load address of the compiled image.


See Also1032059

Package Options dialog box

About packages


Conditionals page
Conditionals page (Package Options dialog box)1032060

See Also

Use the Conditionals page to specify compiler directives. Click the down arrow next to the edit box to choose from a list of previously entered symbols.

Conditional Defines	Symbols referenced in conditional compiler directives. You can separate multiple defines with semicolons.


See Also1032061

Package Options dialog box

About packages


VersionInfo page
VersionInfo page (Package Options dialog box)1032062

See Also

Use this page to enable the version information option and to specify version information for the package.

Module Version Number

Major, Minor, Release, and Build each specify an unsigned integer between 0 and 65,535.  The combined string defines a version number for the application.

Module Attributes

Module attributes are flags that can be included in the version information for informational use only.  If a package is compiled in debug mode, the debug flag will be included in the version information.  You can select each of the remaining flags as needed.

Attribute	Effect

Debug Build	Included to indicate that the package was compiled in debug mode.

Pre-Release	Include to indicate the version is not the commercially released product.

Special Build	Include tp indicate that the version is a variation of the standard release.

Private Build	Include to indicate that the version was not built using standard release procedures.

DLL	Include to indicate that the package includes a dynamic-link library.

Key/Value

A default set of keys are included.

Key	Value indicates

CompanyName	The company that produced the file. Required.

FileDescription	File description. You can display this string in a list box during

installation. Required

FileVersion	File version number. Required.

InternalName	File internal name. If file does not have internal name, use original

filename, without extension. Required.

LegalCopyright	File copyright notices. Optional.

LegalTrademarks	Trademarks and registered trademarks that apply to file. Optional.

OriginalFilename	Original file name, not including path. Required.

ProductName	Name of product that file is distributed with. Required.

ProductVersion	Version of product that file is distributed with. Required.

Comments	Additional information for diagnostic purposes. Optional.

Key entries can be edited by selecting the key and re-entering the name. Key entries can be added by right-clicking within the Key/Value table and selecting Add Key.

Language ID

The language ID indicates which Code Page the users system will require to run the application, that is, it indicates which language the application displays. The following languages are supported.

Constant	Language	Constant	Language

0x0401	Arabic	0x0415	Polish

0x0402	Bulgarian	0x0416	Brazilian Portuguese

0x0403	Catalan	0x0417	Rhaeto-Romanic

0x0404	Traditional Chinese	0x0418	Romanian

0x0405	Czech	0x0419	Russian

0x0406	Danish	0x041A	Croato-Serbian (Latin)

0x0407	German	0x041B	Slovak

0x0408	Greek	0x041C	Albanian

0x0409	U.S. English	0x041D	Swedish

0x040A	Castilian Spanish	0x041E	Thai

0x040B	Finnish	0x041F	Turkish

0x040C	French	0x0420	Urdu

0x040D	Hebrew	0x0421	Bahasa

0x040E	Hungarian	0x0804	Simplified Chinese

0x040F	Icelandic	0x0807	Swiss German

0x0410	Italian	0x0809	U.K. English

0x0411	Japanese	0x080A	Mexican Spanish

0x0412	Korean	0x080C	Belgian French

0x0413	Dutch	0x0C0C	Canadian French

0x0414	Norwegian - Bokml	0x100C	Swiss French

0x0810	Swiss Italian	0x0816	Portuguese

0x0813	Belgian Dutch	0x081A	Serbo-Croatian (Cyrillic)

0x0814	Norwegian - Nynorsk


See Also1032063

Package Options dialog box

About packages


Global page
Global page (Package Options dialog box), Library page (Tools | Environment Options)1032064

See Also

Use this page to specify directories, compiler, and linker options for all packages. Click the down arrow next to the edit boxes to choose from a list of previously entered symbols.

Map file

Select the type of map file produced, if any. The map file is placed in the directory specfied by DCP Directory, and it has a .MAP extension.

Option	Effect

Off	Does not produce map file.

Segments	Linker produces a map file that includes a list of segments, the program start address, and any warning or error messages produced during the link.

Publics	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, and a list of alphabetically sorted public symbols.

Detailed	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, a list of alphabetically sorted public symbols, and an additional detailed segment map. The detailed segment map includes the segment address, length in bytes, segment name, group, and module information.

Messages	Effect

Show Hints 	Causes the compiler to generate hint messages.

Show Warnings 	Causes the compiler to generate warning messages.

Options	Effect

Compile with debug info	Check to compile the package file with debug information. This will make the resulting file larger, but it does not affect memory requirements or performance.

When you compile a package using debug information, you can use the integrated debugger or Turbo Debugger for Windows to debug the library file.

Directories

DPL output directory	Where the compiler should put the compiled package (.dpl) file.

DCP output directory	Specifies a separate directory to contain the .dcp files.

Library path	Specify search paths where compiler can find the source files for the package. The compiler can find only those files listed in Library Path. If you try to build your package with a file not on the library path, you will receive a compiler error.

Aliases

Unit Aliases	Specify alias names for units that may have changed names or were merged into a single unit. The format is <oldunit>=<newunit>. You can separate multiple aliases with semicolons.


See Also1032065

Package Options dialog box

About packages

About package collections


Change Package dialog box
Change Package dialog box (Package editor)1032066

See Also

The Change dialog appears when the Package editor tries to compile a package and detects that the package cannot be built or is incompatible with another package currently loaded by the IDE. This occurs because the package uses a unit or units that are found in another package; select View Details to see which units are causing the problem.

The solution is to add the other package to the "requires" clause of the package you are editing, or simply not use the problem units at all. Click OK to let the Package editor make the proposed changes and continue compiling. Click Cancel to leave the package as it is.


See Also1032067

About packages

Compiling packages


Package Collection editor
Package Collection editor1032068

See Also

The Package Collection editor lets you view and edit the packages and other files associated with a package collection.

File menu

Command	Description

New	Creates a new package collection

Open	Opens a package collection

Save	Saves the current package collection

Save As	Lets you save the current package collection under a different name

Exit	Closes the Package collection editor

Edit menu

Command	Description

Add Package	Lets you add a package to the collection

Remove Package	Removes the selected package from the collection

Add File Group	Lets you specify a set of files associated with the selected package

Remove File Group	Removes the selected file group from the collection

Compile Collection	Compiles the package collection

Collection tree

The collection tree is a hierarchical display of the packages and file groups in a collection.  The controls to the right of the Collection tree change to reflect options for the current selection.

Collection Control	Description

Author/Vendor Name	Optional information about your package collection that appears in the Installation dialog box when users install packages.

Directory List	Lists the default directories where you want the files in your package collection to be installed. Use the Add, Edit, and Delete buttons to edit this list. For example, suppose you want all source code files to be copied to the same directory. In this case, you might enter �Source� as a Directory Name with �C:\MyPackage\Source� as the Suggested Path. The Installation dialog box will display �C:\MyPackage\Source� as the suggested path for the directory.

Package Control	Description

Required Executables Directory	Specifies the directory where you want the .DPL files for packages listed in the requires clause to be installed. (The drop-down list includes the directories you entered under Directory List.) The Package Collection Editor searches for these files using Delphi�s global Library Path and lists them under Required Executable Files.

Required Executables Files	See the description for Required Executables Directory.

Required Libraries Directory	Specifies the directory where you want the .DCP files for packages listed in the requires clause to be installed. (The drop-down list includes the directories you entered under Directory List.) The Package Collection Editor searches for these files using Delphi�s global Library Path and lists them under Required Library Files.

Required Libraries Files	See the description for Required Libraries Directory.

File Group Control	Description

Install Directory	Specifies the directory where you want files in the selected group to be installed. The drop-down list includes the directories you entered under Directory List.

Optional Group	Specifies whether the installation of files in the selected group is optional.

Update Library Search Path	Specifies whether you want the Install Directory to be added to Delphi�s global Library Path as part of the installation.

Included Files	Lists the files you want to include in the selected group. Use the Add, Delete, and Auto buttons to edit the list. The Auto button lets you select all files with specified extensions that are listed in the contains clause of the package; the Package Collection editor uses Delphi�s global Library Path to search for these files.

Package Collection editor speedbar

Button	Description

Add Package	Lets you specify a package to add to the collection

Removed Package	Removes the selected package and any file groups associated with it

Add File Group	Associates a file group with the selected package

Remove File Group	Removes the selected file group

Compile	Compiles the collection


See Also1032069

Package editor

About packages

Design-time packages

Compiling packages

Deploying packages


About packages
About packages1032070

See Also

A package is a special dynamic-link library used by Delphi applications, the Delphi IDE, or both. Runtime packages provide functionality when a user runs an application. Design-time packages are used to install components in Delphi�s IDE and to create special property editors for custom components. A single package can function at both design time and runtime, and design-time packages frequently work by calling runtime packages. To distinguish them from other DLLs, package libraries are stored in files that end with the .DPL (Delphi package library) extension.

Like other runtime libraries, packages contain code that can be shared among applications. For example, most of Delphi�s commonly used components reside in a package called VCL30. Each time you create an application, you can specify that it uses VCL30. When you compile an application created this way, the application�s executable image contains only the code and data unique to it; the common code is in VCL30.DPL. A computer with several package-enabled applications installed on it needs only a single copy of VCL30.DPL, which is shared by all the applications and the Delphi IDE itself.

Delphi ships with several pre-compiled runtime packages, including VCL30, that encapsulate new and previously-existing components. Delphi also uses special design-time packages that facilitate manipulation of components in the IDE.

You can build applications with or without packages. However, if you want to add custom components to the IDE, you must install them as design-time packages.

You can create your own runtime packages to share among applications. If you write Delphi components, you'll compile them into design-time packages before installing them.

Why use packages?

Design-time packages, a standard feature of Delphi, simplify the tasks of distributing and installing custom components. Runtime packages are optional, but offer several advantages over conventional programming. By compiling reused code into a runtime library, you can share it among applications. For example, all of your applications�including the Delphi IDE itself�can access standard components through packages. Since the applications don�t have separate copies of the component library bound into their executables, the executables are much smaller. The result is a dramatic savings in both system resources and hard disk storage. Moreover, packages allow faster compilation because only code unique to the application is compiled with each build.


See Also1032071

About package collections

Using packages in an application

Runtime packages

Design-time packages

Installing component packages

Creating and editing packages

Compiling packages

Deploying packages


Runtime packages
Runtime packages1032072

See Also

Runtime packages are deployed with Delphi applications. They provide functionality when a user runs the application.

To run an application that uses packages, a computer must have both the application�s .EXE file and all the packages (.DPL files) that the application uses. When you deploy an application, you must make sure that users have correct versions of any required DPLs.

Deciding which runtime packages to use

Delphi ships with several precompiled runtime packages, including VCL30, which supply basic Object Pascal and VCL component support. In previous versions of Delphi the functionality provided by these packages was obtained by binding a complete copy of the component library into each application.

The VCL30 package contains the most commonly used components, system functions, and Windows interface elements. It does not include database or Windows 3.1 components, which are available in separate packages. The following table lists the runtime packages shipped with Delphi and the units they contain.

Package	Units

VCL30.DPL	Ax, Buttons, Classes, Clipbrd, Comctrls, Commctrl, Commdlg, Comobj, Comstrs, Consts, Controls, Ddeml, Dialogs, Dlgs, Dsgnintf, Dsgnwnds, Editintf, Exptintf, Extctrls, Extdlgs, Fileintf, Forms, Graphics, Grids, Imm, IniFiles, Isapi, Isapi2, Istreams, Libhelp, Libintf, Lzexpand, Mapi, Mask, Math, Menu, Messages, Mmsystem, Nsapi, Ole2I, Oleconst, Olectnrs, Olectrls, Oledlg, Penwin, Printers, Proxies, Registry, Regstr, Richedit, Shellapi, Shlobj, Stdctrls, Stdvcl, Sysutils, Tlhelp32, Toolintf, Toolwin, Typinfo, Vclcom, Virtintf, Windows, Wininet, Winsock, Winspool, Winsvc

VCLX30.DPL	Checklst, Colorgrd, Ddeman, Filectrl, Mplayer, Outline, Tabnotbk, Tabs

VCLDB30.DPL	Bde, Bdeconst, Bdeprov, Db, Dbcgrids, Dbclient, Dbcommon, Dbconsts, Dbctrls, Dbgrids, Dbinpreq, Dblogdlg, Dbpwdlg, Dbtables, Dsintf, Provider, SMintf

VCLDBX30.DPL	Dblookup, Report

DSS30.DPL	Mxarrays, Mxbutton, Mxcommon, Mxconsts, Mxdb, Mxdcube, Mxdssqry, Mxgraph, Mxgrid, Mxpivsrc, Mxqedcom, Mxqparse, Mxqryedt, Mxstore, Mxtables, Mxqvb

INET30.DPL	Cgiapp, Copyprsr, Httpapp, Isapiapp, Masks, Scktcomp, Syncobjs, Webconst

INETDB30.DPL	Dbweb

QRPT30.DPL	Qr2const, Qrabout, Qralias, Qrctrls, Qrdatasu, Qrexpbld, Qrextra, Qrprev, Qrprgres, Qrprntr, Qrqred32, Quickrpt

TEE30.DPL	Arrowcha, Bubblech, Chart, Ganttch, Series, Teeconst, TeeFunci, TeEngine, Teeprocs, Teeshape

TEEDB30.DPL	Dbchart, Qrtee

IBEVNT30.DPL	Ibctrls, Ibevnts, Ibproc32, Ibreg

Suppose you want to create a client/server database application that uses packages. In this case, you need at least two runtime packages: VCL30 and VCLDB30. If you want to use Outline components in your application, then you also need VCLX30. To use these packages, choose Project|Options, select the Packages tab, and enter the following list in the Runtime Packages edit box.

VCL30;VCLDB30;VCLX30

Actually, you don�t have to include VCL30 in this list, because VCL30 is referenced in the requires clause of VCLDB30. Your application will compile just the same whether or not VCL30 is included in the list.

Custom packages

A custom package is either a DPL you code and compile yourself, or a precompiled package from a third-party vendor. To use a custom runtime package with an application, choose Project|Options and add the name of the package to the Runtime Packages edit box on the Packages page. For example, suppose you created a statistical package called STATS.DPL. To use it in an application, the line you enter in the Runtime Packages edit box might look like this:

VCL30;VCLDB30;STATS

If you create your own packages, you can add them to the list as needed.


See Also1032073

About packages

Using packages in an application

Deploying packages


Using packages in an application
Using packages in an application1032074

See Also

To use packages in an application:

1.	Load or create a project in the IDE.

2.	Choose Project|Options.

3.	Choose the Packages tab.

4.	Select the Build with Runtime Packages check box, and enter one or more package names in the edit box underneath. (Runtime packages associated with installed design-time packages are already on the list.) To add a package to an existing list, click the Add button and enter the name of the new package in the Add Package dialog box. To browse from a list of available packages, click the Add button, then click the Browse button in the Add Package dialog box box.

If you use the Search Path edit box in the Add Package dialog box, you will be changing the global Library Path for Delphi.

You do not need to include file extensions with package names. If you type directly into the Runtime Packages edit box, be sure to separate multiple names with semicolons. For example:

VCL30;VCLDB30;VCLDBX30

Packages listed in the Runtime Packages edit box are automatically linked into your application when you compile. Duplicate package names are ignored, and if the edit box is empty the application is compiled without packages. Runtime packages are selected for the current project only. To make the current choices into automatic defaults for new projects, select the �Default� check box at the bottom of the dialog box.

When you create an application with packages, you still need to include the names of the original Delphi units in the uses clause of your source files. For example, the source file for your main form may begin like this:

unit MainForm;

interface

uses

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

Each of the units referenced in this example is contained in the VCL30 package, but you must keep these references in the uses clause, even if you use VCL30 in your application, or you will get compiler errors.


See Also1032075

About packages

Runtime packages

Deploying packages


Design-time packages
Design-time packages1032076

See Also

Design-time packages are used to install components on the IDE�s Component palette and to create special property editors for custom components.

Delphi ships with the following design-time component packages preinstalled in the IDE.

Package	Component palette pages

DCLSTD30.DPL	Standard, Additional, System, Win32, Dialogs

DCLTEE30.DPL	Additional (TChart component)

DCLDB30.DPL	Data Access, Data Controls

DCL31W30.DPL	Win 3.1

DCLNET30.DPL	Internet

DCLISP30.DPL	Internet

DCLSMP30.DPL	Samples

DCLOCX30.DPL	ActiveX

DCLQRT30.DPL	QReport

DCLDSS30.DPL	Decision Cube

IBEVNT30.DPL	Samples (IBEventAlerter component)

These design-time packages work by calling runtime packages, which they reference in their requires clauses. For example, STDLIB references VCL30. STDLIB itself contains additional functionality that makes most of the standard components available on the Component palette.

In addition to preinstalled packages, you can install your own component packages, or component packages from third-party developers, in the IDE. The DCLUSR30 design-time package is provided as a default container for new components.


See Also1032077

About packages

Installing component packages

Creating and editing packages

About package collections


Installing component packages
Installing component packages1032078

See Also

In Delphi, all components are installed in the IDE as packages. If you�ve written your own components, you can create and compile a package that contains them. The unit file that contains your component source code must correspond to the model for component source files described in the Delphi Developer�s Guide.

To install or uninstall your own components, or components from a third-party vendor:

1.	If you are installing a new package, copy or move the necessary files to a local directory.

If the package is shipped with separate .DPL, .DCP, and .DCU files, be sure to copy all of them.

If the package is shipped as a .DPC (package collection) file, only the one file need be copied; the .DPC file contains the other files.

The directory where you store the .DCP file�and the .DCU files, if they are included with the distribution�must be in the Delphi Library Path. It is customary to put executable files in the Delphi \BIN directory.

2.	Choose Component|Install Packages from the IDE menu, or choose Project|Options and click the Packages tab.

3.	A list of available packages appears under �Design packages�.

To install a package in the IDE, select the check box next to it.

To uninstall a package, deselect its check box.

To see a list of components included in an installed package, select the package and click Components.

To add a package to the list, click Add and browse in the Open Package dialog box for the directory where the .DPL or .DPC file resides (see step 1). Select the .DPL or .DPC file and click Open. If you select a .DPC file, a new dialog box will appear to handle the extraction of the .DPL and other files from the package collection.

To remove a package from the list, select the package and click Remove.

4.	Click OK.

Unless you change the default settings, new projects are created with all available packages installed. To make the current installation choices into the automatic default for new projects, select the �Defaults� check box at the bottom of the dialog box.

To remove components from the Component palette without uninstalling a package, select Component|Configure Palette, or select Tools|Environment Options and click the Palette tab. The Palette options tab lists each installed component along with the name of the Component palette page where it appears. Selecting any component and clicking Hide removes the component from the palette.


See Also1032079

About packages

Design-time packages

About package collections

Creating and editing packages


Creating and editing packages
Creating and editing packages1032080

See Also

A package source file does not contain type, data, procedure, or function declarations. Instead it contains a name for the package, a list of other �required� packages, and names of the source-code units that should be bound into the package.

To create a package you must specify:

A name for the package.

A list of other packages required by or linked to the new package.

A list of unit files to be contained by, or bound into, the package when it is compiled. The package is essentially a wrapper for these source-code units, which contain the functionality of the compiled DPL.

Package source files, which end with the .DPK extension, are generated by the Package editor.

To create a package:

1.	Load or create a project in the IDE.

2.	Choose File|New, select the Package icon, and click OK.

3.	In the New Package dialog box, enter a file name and (optionally) a description. You can include a directory path with the name; otherwise, the package will reside in the current directory. To open a file/directory selection dialog box, click the Browse button. If you type a file name directly in the New Package dialog box, the .DPK extension will be added automatically.

Package names must be unique within a project. If you name a package �STATS�, the Package editor generates a source file for it called �STATS.DPK�; the compiler generates an executable and a binary image called �STATS.DPL� and �STATS.DCP�, respectively. Use �STATS� to refer to the package in the requires clause of another package, or when using the package in an application.

4.	Click OK to open the Package editor.

5.	Choose the Contains tab, then click the Add speed button.

6.	When the Add dialog box opens, you can add an existing unit file to the package�s contains clause, create a new component that descends from an existing component, or import an ActiveX component.

To add a unit file to the package�s contains clause, choose the Add Unit tab and enter a file in the Unit File Name edit box. You can specify an entire directory path with the file name, or edit the search path in the Search Path edit box; if you edit the search path, you will be changing the global Library Path for Delphi. To add more unit files to the package, close the Add dialog box by clicking OK, then click the Add speed button again in the Package editor.

To create a new component, choose the New Component tab. Enter the new component�s class name, the name of its immediate ancestor, the name of the unit file where the component�s declaration should be written, and the page on the Component palette where you want the new component displayed. You can specify an entire directory path with the file name, or edit the search path in the Search Path edit box; if you edit the search path, you will be changing the global Library Path for Delphi.

To import an ActiveX component, choose the Import ActiveX tab and select a registered component from the list box. To register a new component, click Add. To unregister a component, click Remove.

7.	In the Package editor, choose the Requires tab to see a list of other packages in the requires clause of the package you are editing. VCL30 is listed by default. If you want to add more packages to the requires clause, click the Add speed button and proceed as in step 6 above.

8.	Click the Options speed button and select the Description tab.

Under �Usage options�, check �Design package�, �Runtime package�, or both. Selecting only one of these options turns on the $RUNONLY or $DESIGNONLY compiler directive. (See �Inserting package-specific compiler directives in code�.) To create a design-time package that is not installable in the IDE (but may still be called by other design-time packages), deselect both check boxes.

Under �Build control�, select �Rebuild as needed� or �Explicit rebuild�. �Explicit rebuild� turns on the -Z ($IMPLICITBUILD OFF) compiler switch, which prevents implicit recompilation of the package. (See �Using the command-line compiler�.)

Click OK to close the Package Options dialog box and save your changes.

9.	In the Package editor, click the Build speed button to compile your package.

Clicking the Build speed button compiles your package into a DPL, but does not save the package source (.DPK) file. To save the .DPK file, right-click and select Save Package, or choose File|Save from Delphi�s main menu bar.

Editing an existing package in the Package editor:

There are several ways to open an existing package in the Package editor.

Choose File|Open (or File|Reopen) and select a .DPK file.

Choose Component|Install Packages, select a package from the Design Packages list, and click the Edit button.

Choose Component|Add Unit To Package and click the Add To Existing tab. Then select a package and a unit file to add to the package�s contains clause.

You can also open a package by choosing File|Open and selecting a .DPL file. However, the Package editor always looks for a .DPK file to open, even if you select a .DPL. If it cannot find the .DPK file, the Package editor is sometimes able to open the .DPL on a read-only basis; in this case, you can resave the package as a .DPK for further editing.

The Contains page in the Package editor displays a list of unit files contained in the current package. You can add or remove files by clicking the appropriate speed button. To open a unit file in the Code editor, select the file, right-click, and choose View Unit.

The Requires page displays a list of other packages required by (linked to) the current package. You can add or remove files by clicking the appropriate speed button. To open one of the required packages in a new Package editor, select the package, right-click, and choose View Required Package.

The Package Options speed button lets you edit the package�s description or set compiler and library options.

Editing package source files manually

Package source files, like project files, are generated by Delphi from information you supply. Like project files, they can also be edited manually. A package source file should be saved with the .DPK (Delphi package) extension to avoid confusion with other files containing Object Pascal source code.

To open a package source file in the Code editor:

1.	Open the package in the Package editor.

2.	Right-click in the Package editor and select View Package Source.

For example, the following code declares the VCLDB30 package.

package VCLDB30;

requires VCL30;

contains Db, Dbcgrids, Dbctrls, Dbgrids, Dbinpreq, Dblogdlg, Dbpwdlg, Dbtables;

end.

The package heading specifies the name for the package.

The requires clause lists other, external packages used by the current package. If a package does not reference other packages, then it does not need a requires clause.

The contains clause identifies the unit files to be compiled and bound into the package.


See Also1032081

About packages

Using packages in an application

Compiling packages

Deploying packages

Installing component packages

About package collections


Compiling packages
Compiling packages1032082

See Also

You can compile a package from the IDE or from the command line. When you rebuild any project that contains a package, the package is implicitly recompiled if necessary.

To recompile a package by itself from the IDE:

1.	Choose File|Open.

2.	Select �Delphi package source (*.dpk)� from the �Files of type� drop-down list.

3.	Select a .DPK file in the dialog box.

4.	When the Package editor opens, click the Build speed button.

You can insert compiler directives into your package source code. For more information, see �Inserting package-specific compiler directives in code�, below.

If you compile from the command line, new package-specific switches are available. For more information, see Compiling packages.

Inserting package-specific compiler directives in code

The following table lists package-specific compiler directives that you can insert into your source code.

Directive	Purpose

{$IMPLICITBUILD OFF}	Prevents a package from being implicitly recompiled later. Use in .DPK files when compiling packages that provide low-level functionality, that change infrequently between builds, or whose source code will not be distributed.

{$G-} or {IMPORTEDDATA OFF}	Disables creation of imported data references. This directive increases memory-access efficiency, but prevents the unit where it occurs from referencing variables in other packages.

{$WEAKPACKAGEUNIT ON}	Packages unit �weakly�. See �The $WEAKPACKAGEUNIT directive� below.

{$DENYPACKAGEUNIT ON}	Prevents unit from being placed in a package.

{$DESIGNONLY ON}	Compiles the package for installation in the IDE. (Put in .DPK file.)

{$RUNONLY ON}	Compiles the package as runtime only. (Put in .DPK file.)

Note:	Including {$DENYPACKAGEUNIT ON} in your source code prevents the unit file from being packaged. Including {$G-} or {IMPORTEDDATA OFF} may prevent a package from being used in the same application with other packages. Packages compiled with the {$DESIGNONLY ON} directive should not ordinarily be used in applications, because they contain extra code required by the IDE. Other compiler directives may be included, if appropriate, in package source code. See the Object Pascal Language Guide for information on compiler directives not discussed here.

The $WEAKPACKAGEUNIT directive

The $WEAKPACKAGEUNIT directive affects the way a .DCU file is stored in a package�s .DCP and .DPL files. If {$WEAKPACKAGEUNIT ON} appears in a unit file, the compiler omits the unit from DPLs when possible, and creates a non-packaged local copy of the unit when it is required by another application or package. A unit compiled with this directive is said to be �weakly packaged�.

For example, suppose you�ve created a package called PACK that contains only one unit, UNIT1. Suppose UNIT1 does not use any further units, but it makes calls to RARE.DLL. If you put {$WEAKPACKAGEUNIT ON} in UNIT1.PAS when you compile your package, UNIT1 will not be included in PACK.DPL; you will not have to distribute copies of RARE.DLL with PACK. However, UNIT1 will still be included in PACK.DCP. If UNIT1 is referenced by another package or application that uses PACK, it will be copied from PACK.DCP and compiled directly into the project.

Now suppose you add a second unit, UNIT2, to PACK. Suppose that UNIT2 uses UNIT1. This time, even if you compile PACK with {$WEAKPACKAGEUNIT ON} in UNIT1.PAS, the compiler will include UNIT1 in PACK.DPL. But other packages or applications that reference UNIT1 will use the (non-packaged) copy taken from PACK.DCP.

Note:	Unit files containing the {$WEAKPACKAGEUNIT ON} directive must not have global variables, initialization sections, or finalization sections.

The $WEAKPACKAGEUNIT directive is an advanced feature intended for developers who distribute their DPLs to other Delphi programmers. It can help you to avoid distribution of infrequently used DLLs, and to eliminate conflicts among packages that may depend on the same external library.

For example, Delphi�s PenWin unit references PENWIN.DLL. Most projects don�t use PenWin, and most computers don�t have PENWIN.DLL installed on them. For this reason, the PenWin unit is weakly packaged in VCL30. When you compile a project that uses PenWin and the VCL30 package, PenWin is copied from VCL30.DCP and bound directly into your project; the resulting executable is statically linked to PENWIN.DLL.

If PenWin were not weakly packaged, two problems would arise. First, VCL30 itself would be statically linked to PENWIN.DLL, and so you could not load it on any computer which didn�t have PENWIN.DLL installed. Second, if you tried to create a package that contained PenWin, a compiler error would result because the PenWin unit would be contained in both VCL30 and your package. Thus, without weak packaging, PenWin could not be included in standard distributions of VCL30.

Using the command-line compiler

When you compile from the command line, you can use the package-specific switches listed in the following table.

Switch	Purpose

-$G-	Disables creation of imported data references. Using this switch increases memory-access efficiency, but prevents packages compiled with it from referencing variables in other packages.

-LEpath	Specifies the directory where the package DPL file will be placed.

-LNpath	Specifies the directory where the package DCP file will be placed.

-Z	Prevents a package from being implicitly recompiled later. Use when compiling packages that provide low-level functionality, that change infrequently between builds, or whose source code will not be distributed.

Note:	Using the -$G- switch may prevent a package from being used in the same application with other packages. Other command-line options may be used, if appropriate, when compiling packages. See the Object Pascal Language Guide for information on command-line options not discussed here.

Package files created by a successful compilation

To create a package you compile a source file that has a .DPK extension. The base name of the .DPK file becomes the base name of the files generated by the compiler. For example, if you compile a package source file called TRAYPAK.DPK, the compiler creates a package called TRAYPAK.DPL.

The following table lists the files produced by the successful compilation of a package.

File extension	Contents

DCP	A binary image containing a package header and the concatenation of all DCU files in the package. A single DCP file is created for each package. The base name for the DCP is the base name of the DPK source file.

DCU	A binary image for a unit file contained in a package. One DCU is created, when necessary, for each unit file.

DPL	The runtime package. This file is a Windows DLL with special Delphi-specific features. The base name for the DPL is the base name of the DPK source file.


See Also1032083

About packages

Creating and editing packages

Installing component packages

About package collections


packages, deploying;packages;
Deploying packages1032084

See Also

Deploying applications that use packages

When distributing an application that uses runtime packages, make sure that your users have the application�s .EXE file as well as all the library (.DPL or .DLL) files that the application calls. If the library files are in a different directory from the .EXE file, they must be accessible through the user�s Path. You might want to follow the convention of putting library files in the Windows\System directory. If you use InstallShield Express, your installation script can check the user�s system for any packages it requires before blindly reinstalling them.

Distributing packages to other developers

If you distribute runtime or design-time packages to other Delphi developers, be sure to supply both .DCP and .DPL files. You will probably want to include .DCU files as well.


See Also1032085

About packages

Using packages in an application

Runtime packages


package collections; packages, deploying;
About package collections1032086

See Also

Package collections (.DPC files) offer a convenient way to distribute packages to other developers. Each package collection contains one or more packages, including DPLs and any additional files you want distribute with them. When a package collection is selected for IDE installation, its constituent files are automatically extracted from their .DPC container; the Installation dialog box offers a choice of installing all packages in the collection or installing packages selectively.

To create a package collection:

1.	Choose Tools|Package Collection Editor to open the Package Collection editor.

2.	Click the Add Package speed button, then select a DPL in the Select Package dialog box and click Open. To add more DPLs to the collection, click the Add Package speed button again. A tree diagram on the left side of the Package editor will display the DPLs as you add them. To remove a package, select it and click the Remove Package speed button.

3.	Select the Collection node at the top of the tree diagram. On the right side of the Package Collection editor, three fields will appear:

In the File Name edit box, type a name for the package collection file you want to produce. You can include a directory path with the name; otherwise, the package collection file will reside in the current directory. Do not include an extension.

In the Author/Vendor Name edit box, you can enter optional information about your package collection that will appear in the Installation dialog box when users install packages.

Under Directory List, list the default directories where you want the files in your package collection to be installed. Use the Add, Edit, and Delete buttons to edit this list. For example, suppose you want all source code files to be copied to the same directory. In this case, you might enter �Source� as a Directory Name with �C:\MyPackage\Source� as the Suggested Path. The Installation dialog box will display �C:\MyPackage\Source� as the suggested path for the directory.

4.	In addition to DPLs, your package collection can contain .DCP, .DCU, and .PAS (unit) files, documentation, and any other files you want to include with the distribution. Ancillary files are placed in file groups associated with specific packages (DPLs); the files in a group are installed only when their associated DPL is installed. To place ancillary files in your package collection, select a DPL in the tree diagram and click the Add File Group speed button; type a name for the file group. Add more file groups, if desired, in the same way. When you select a file group, new fields will appear on the right in the Package Collection editor:

In the Install Directory list box, select the directory where you want files in this group to be installed. The drop-down list includes the directories you entered under Directory List in step 3, above.

Select the �Optional Group� check box if you want installation of the files in this group to be optional.

Select the �Update Library Search Path� check box if you want the Install Directory to be added to Delphi�s global Library Path as part of the installation.

Under Include Files, list the files you want to include in this group. Use the Add, Delete, and Auto buttons to edit the list. The Auto button allows you to select all files with specified extensions that are listed in the contains clause of the package; the Package Collection editor uses Delphi�s global Library Path to search for these files.

5.	You can select installation directories for the packages listed in the requires clause of any package in your collection. When you select a DPL in the tree diagram, four new fields appear on the right side of the Package Collection editor:

In the Required Executables list box, select the directory where you want the .DPL files for packages listed in the requires clause to be installed. (The drop-down list includes the directories you entered under Directory List in step 3, above.) The Package Collection Editor searches for these files using Delphi�s global Library Path and lists them under Required Executable Files.

In the Required Libraries list box, select the directory where you want the .DCP files for packages listed in the requires clause to be installed. (The drop-down list includes the directories you entered under Directory List in step 3, above.) The Package Collection Editor searches for these files using Delphi�s global Library Path and lists them under Required Library Files.

6.	To build your package collection, click the Compile speed button.

Clicking the Compile speed button generates a .DPC file with the name you have selected, but does not save the package collection source file. To save the source file for future editing, select File|Save. Package collection source files should be saved with the .PCE extension. To edit or recompile an existing .PCE file, select File|Open in the Package Collection editor.


See Also1032087

About packages


Run Menu
Run menu1033001

The Run menu commands help you debug your program from within Delphi. The following commands form the core functionality of the integrated debugger:

Run	Compiles and executes your application

Parameters	Specifies startup parameters for your application

Register ActiveX	Registers the project in the Windows registry. Available when the current project is an ActiveX project.

Unregister ActiveX Servers	Removes  the project from the Windows registry. Available when the current project is an ActiveX project.

Step Over	Executes a program one line at a time, stepping over procedures while executing them as a single unit

Trace Into	Executes a program one line at a time, tracing into procedures and following the execution of each line

Trace To Next Source Line	Executes the program, stopping at the next executable source line in your code

Run To Cursor	Runs the loaded program up to the location of the cursor in the Code Editor window

Show Execution Point	Positions the cursor at the execution point in an edit window

Program Pause	Temporarily pauses the execution of a running program

Program Reset	Ends the current program run and releases it from memory

Add Watch	Opens the Watch Properties dialog box, where you can create and modify watches

Add Breakpoint	Opens the Edit Breakpoint dialog box, where you can create and modify breakpoints

Evaluate/Modify	opens the Evaluate/Modify dialog box, where you can evaluate or change the value of an existing expression

Note:	The integrated debugger commands become accessible when you generate symbolic debug information for the project you are working on.


Run|Run
Run | Run1033002

See also

Choose Run|Run to compile and execute your application, using any startup parameters you specified in the Parameters dialog box.

If you have modified the source code since the last compilation, the compiler recompiles those changed modules and relinks your application.

If the compiler encounters an error, it displays an Error dialog box. When you choose OK to dismiss the dialog box, the Code Editor places the cursor on the line of code containing the error.

The compiler builds .EXE files according to the following rules:

The project (.DPR) file is always recompiled.

If the source code of a unit has changed since the last time the unit was compiled, the unit is compiled. When a unit is compiled, Delphi creates a file with a .DCU extension for that unit.

If Delphi cannot locate the source code for a unit, that unit is not recompiled.

If the interface section of a unit has changed, all the other units that depend on the changed unit are recompiled.

If a unit links in an .OBJ file (external routines), and the .OBJ file has changed, the unit is recompiled.

If a unit contains an Include file. and the Include file has changed, the unit is recompiled.


See also1033003

The Delphi Debugger

Controlling program execution

Build commands keyboard shortcuts

Compiling, building and running projects


Register or unregister an ActiveX server
Register or unregister an ActiveX server1033004

See also

Run | Register an ActiveX server

or

Run | Unregister an ActiveX server.

These options are available only for ActiveX projects.

If the project has not been compiled previously, it will be compiled when either of these options is selected.

Register an Active X Server 	Adds the server to the Windows registry file.

Unregister an ActiveX Server 	Removes the server from the Windows registry file.


Run|Parameters
Run | Parameters1033005

See also

Choose Run|Parameters to open the Parameters dialog box.

Parameters dialog box

Use this dialog box to pass command-line parameters to your application when you run it, just as if you were running the application from the Program Manager File|Run menu.

You can use these parameters with the ParamCountand ParamStr() functions.

Run Parameters	Enter the parameters you want to pass to your application when it starts, or use the drop-down button to choose from a history of previously specified parameters. Parameters take effect only when your application is started. Do not enter the application name in this edit box.


See also1033006

The Delphi Debugger


Run|Step Over
Run | Step Over1033007

See also

Choose Run|Step Over to execute a program one line at a time, stepping over procedures while executing them as a single unit.

The Step Over command executes the program statement highlighted by the execution point and advances the execution point to the next statement.

If you issue the Step Over command when the execution point is located on a function call, the debugger runs that function at full speed, then positions the execution point on the statement that follows the function call.

If you issue Step Over when the execution point is positioned on the end statement of a routine, the routine returns from its call, and the execution point is placed on the statement following the routine call.

The debugger considers multiple program statements on one line of text as a single line of code; you cannot individually debug multiple statements contained on a single line of text. The debugger also considers a single statement that spans several lines of text as a single line of code.

By default, when you initiate a debugging session with Run|Step Over, Delphi moves the execution point to the first line of code that contains debugging information (this is normally a location that contains user-written code). To step over start-up code that Delphi automatically generates, see Stepping through code.

In addition to stepping over procedures, you can trace into them, following the execution of each line. Use Run|Trace Into to execute each line of a procedure.

An alternative way to perform this command is:
Choose the Step Over speed bar button.


See also1033008

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Trace Into
Run | Trace Into1033009

See also

Choose Run|Trace Into to execute a program one line at a time, tracing into procedures and following the execution of each line.

The Trace Into command executes the program statement highlighted by the execution point and advances the execution point to the next statement.

If you issue the Trace Into command when the execution point is located on a function call, the debugger traces into the function, positioning the execution point on the function痴 first statement.

If you issue Step Over when the execution point is positioned on the end statement of a routine, the routine returns from its call, and the execution point is placed on the statement following the routine call.

If the execution point is located on a function call that does not have debugging information, such as a library function, the debugger runs that function at full speed, then positions the execution point on the statement following the function call.

By default, when you initiate a debugging session with Run|Trace Into, Delphi moves the execution point to the first line of code that contains debugging information (this is normally a location that contains user-written code). To trace into start-up code that Delphi automatically generates, see Stepping through code.

In addition to tracing into procedures, you can step over them, executing each procedure as a single unit. Use Run|Step Over to execute procedures as a single unit.

An alternative way to perform this command is:
Choose the Trace Into speedbar button.


See also1033010

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Trace to Next Source Line
Run | Trace To Next Source Line1033011

See also

Use this command to stop on the next source line in your application, regardless of the control flow. For example, if you select this command when stopped at a Windows API call that takes a callback function, control will return to the next source line, which in this case is the callback function.


See also1033012

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Run To Cursor
Run | Run To Cursor1033013

See also

Choose Run|Run To Cursor to run the loaded program up to the location of the cursor in the Code Editor window.

When you run to the cursor, your program is executed at full speed, then pauses and places the execution point on the line of code containing the cursor.

You can use Run To Cursor to run your program and pause before the location of a suspected problem. You can then use Run|Step Over or Run|Trace Into to control the execution of individual lines of code.

An alternative way to perform this command is:
Choose Run To Cursor from the Code Editor context menu.


See also1033014

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Show Execution Point
Run | Show Execution Point1033015

See also

Choose Run|Show Execution Point to position the cursor at the execution point in an edit window. If you closed the edit window containing the execution point, Delphi opens an edit window displaying the source code at the execution point.


See also1033016

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Program Pause
Run | Program Pause1033017

See also

Choose Run|Program Pause to temporarily pause the execution of a running program.

The debugger pauses program execution and positions the execution point on the next line of code to execute. You can examine the state of your program in this location, then continue debugging by running, stepping, or tracing.

If your program assumes control and does not return to the debugger--for example, if it is running in an infinite loop--press Ctrl+Alt+Sys Req to stop your program. You might need to press this key combination several times before your program actually stops, because the command does not work if Windows kernel code is executing.

In addition to temporarily pausing a program running in the debugger, you can also stop a program and release it from memory. Use Run|Program Reset to stop a running program and release it from memory.


See also1033018

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Program Reset
Run | Program Reset1033019

See also

Choose Run|Program Reset to end the current program run and release it from memory.

Use Program Reset to restart a program from the beginning, such as when you step past the location of a bug, or if variables or data structures become corrupted with unwanted values.

When you reset a program, Delphi performs the following actions:

Closes all open program files

Releases resources allocated by calls to the VCL

Clears all variable settings

Resetting a program does not delete any breakpoints or watches you have set, which makes it easy to resume a debugging session.

Windows resources

Resetting a program does not necessarily release all Windows resources allocated by your program. In most cases, all resources allocated by VCL routines are released. However, Windows resources allocated by code which you have written might not be properly released.

If your system becomes unstable, through either multiple hardware or language exceptions or through a loss of system resources as a resul of resetting your program, you should exit Delphi before restarting your debugging session.


See also1033020

The Delphi Debugger

Controlling program execution

Debug commands keyboard shortcuts


Run|Add Watch
Run | Add Watch1033021

See also

The Add Watch command opens the Watch Properties dialog box, where you can create and modify watches. After you create a watch, use the Watch List window to display and manage the current list of watches.

Alternate ways to perform this command are:

Choose Add Watch at Cursor from the Code Editor context menu.

Choose Add Watch from the Watch List context menu.

Right-click an existing watch in the Watch List window and choose Edit Watch from the Watch List context menu.


See also1033022

The Delphi Debugger

Watching expressions

Debug commands keyboard shortcuts


Run|Add Breakpoint
Run | Add Breakpoint1033023

See also

The Add Breakpoint command opens the Edit Breakpoint dialog box, where you can create and modify breakpoints.

Alternate ways to perform this command are:

Choose Add Breakpoint from the Breakpoint List context menu.

Right-click an existing breakpoint in the Breakpoint List window and choose Edit Breakpoint from the Breakpoint List context menu.


See also1033024

The Delphi Debugger

Using breakpoints

Controlling program execution

Debug commands keyboard shortcuts


Run|Evaluate/Modify
Run | Evaluate/Modify1033025

See also

The Evaluate/Modify command opens the Evaluate/Modify dialog box, where you can evaluate or change the value of an existing expression.

An alternate way to perform this command is:
Choose Evaluate/Modify from the Code Editor context menu.


See also1033026

The Delphi Debugger

Debug commands keyboard shortcuts


Search menu
Search menu1034001

Search commands keyboard shortcuts

Use the Search menu commands to locate text, errors, objects, units, variables, and symbols in the Code Editor.

Find	Searches for specific text, and highlights first occurrence in the code editor.

Find In File	Searches for specific text, displays each occurrence in a window at the bottom of the code editor.

Replace	Searches for specific text and replace it with new text

Search Again	Repeats search

Incremental Search	Searches for text as you type

Go to Line Number	Moves cursor to specific line number

Find Error	Searches for most recent run-time error

Browse Symbol	Searches for specified symbol


Search|Find
Search | Find1034002

See also

Choose Search|Find to display the Find Text dialog box.

Find Text dialog box

Select the Find tab to specify text you want to locate and to set options that affect the search. Find locates the line of code containing the first occurrence of the string and highlights it.

Text to find

Enter a search string; or, click the down arrow next to the input box to select from a list of previously entered search strings.

Options	Specifies attributes for the search string:

Case sensitive	Differentiates uppercase from lowercase when performing a search.

Whole words only	Searches for words only. (With this option off, the search string might be found within longer words.)

Regular expressions	Recognizes regular expressions in the search string.

Direction	Specifies which direction you want to search, starting from the current cursor position:

Forward	From the current position to the end of the file. Forward is the default Direction setting.

Backward	From the current position, to the beginning of the file.

Scope	Determines how much of the file is searched:

Global	Searches the entire file, in the direction specified by the Direction setting. Global is the default scope.

Selected text	Searches only the selected text, in the direction specified by the Direction setting. You can use the mouse or block commands to select a block of text.

Origin	Specifies where the search should start:

From cursor	The search starts at the cursor's current position, and then proceeds either forward to the end of the scope, or backward to the beginning of the scope depending on the Direction setting. From Cursor is the default Origin setting.

Entire scope	The search covers either the entire block of selected text or the entire file (no matter where the cursor is in the file), depending upon the Scope options.


See also1034003

Block commands keyboard shortcuts (brief)

Block commands keyboard shortcuts (default and classic)

Block commands keyboard shortcuts (Epsilon)

Search commands keyboard shortcuts


Search | Find in file
Search | Find in files1034004

See also

Choose Search|Find in files to list occurrences of a specified string.

Find in file dialog box

Select the Find in Files tab to specify text you want to locate and to set options that affect the search. Each occurrence of the string is listed in a box at the bottom of the Code Editor. Double-click a list entry to move to that line in the code file.

Text to find

Enter a search string.  To select from a list of previously entered search strings, click the down arrow next to the input box.

Options	Specifies attributes for the search string:

Case sensitive	Differentiates uppercase from lowercase when performing a search.

Whole words only	Searches for words only. (With this option off, the search string might be found within longer words.)

Regular expressions	Recognizes regular expressions in the search string.

Where	Specifies which files you wish to search:

Search all files in project	Searches all files in the open project.

Search all open files	Searches files that are currently open.

Search in directories	When selected, the Search Directories options are available.  The search proceeds through all files indicated.

Search directory options	Defines the full path to file(s) to be searched:

File masks	Specify the path of the files to be searched.  Wild card entries 	are accepted (such as, *.pas).

Include subdirectories	If selected, sub-directories from the directory path specified are 	also searched.


See also1034005

Block commands keyboard shortcuts (brief)

Block commands keyboard shortcuts (default and classic)

Block commands keyboard shortcuts (Epsilon)

Search commands keyboard shortcuts


Search|Replace
Search | Replace1034006

See also

Choose Search|Replace to display the Replace Text dialog box.

Replace Text

Use this dialog box to specify text you want to search for and then replace with other text (or with nothing).

Most components of the Replace Text dialog box are identical to those in the Find Text dialog box.

Text to find

Enter a search string. To select from a list of previously entered search strings, click the down arrow next to the input box

Replace with

Enter the replacement string. To select from a list of previously entered search strings, click the down arrow next to the input box. To replace the text with nothing, leave this input box blank.

Options	Specifies attributes for the search strings:

Case sensitive	Differentiates uppercase from lowercase when performing a search.

Whole words only	Searches for words only. (With this option off, the search string might be found within longer words.)

Regular expressions	Recognizes specific regular expressions in the search string.

Prompt on replace	Prompts you before replacing each occurrence of the search string. When Prompt on replace is off, the editor automatically replaces the search string.

Direction	Specifies which direction you want to search the file, starting from the current cursor position:

Forward	From the current position, to the end of the file. Forward is the default Direction setting.

Backward	From the current position, to the beginning of the file.

Scope	Determines how much of the file is searched:

Global	The entire file, in the direction specified by the Direction setting. Global is the default scope.

Selected text	Only the selected text, in the direction specified by the Direction setting. To select a block of text, use the mouse or block commands.

Origin	Specifies where the search should start:

From cursor	The search starts at the cursor's current position, and then proceeds either forward to the end of the scope, or backward to the beginning of the scope depending on the Direction setting. From cursor is the default Origin setting.

Entire scope	The search covers either the entire block of selected text or the entire file (no matter where the cursor is in the file), depending upon the Scope options.

Replace All

To replace every occurrence of the search string, click Replace All. If you have checked the Prompt on Replace option, the Confirm dialog box appears on each occurrence of the search string.


Search|Search Again
Search | Search Again1034007

Choose Search|Search Again to repeat the last Find, or Replace command.

The settings last made in the Find Text or Replace Text dialog box remain in effect when you choose Search Again. For instance, if you have not cleared the Replace Text settings, the Search Again command searches for the string you last specified and replaces it with the text specified in the Replace Text dialog box.


Search|Incremental Search
Search | Incremental Search1034008

Choose Search|Incremental Search to bypass the Find Text dialog box by moving the cursor directly to the next occurrence of text that you type.

When you are performing an incremental search, the Code Editor status line reads "Searching For:" and displays each letter you have typed.

For example, if you type "class" the cursor moves to the next occurrence of the word, highlighting each letter as you type it. This behavior continues until a new occurrence of the string is not found or you press Enter or Escape.

Here are some Incremental Search keystroke options:

Option	Effect

Backspace	Remove the last character from the search string and move to the previous match.

F3	Repeat search   (Default keybinding)

Ctrl+L	Repeat search   (Classic keybinding)

Ctrl+S	Repeat search   (Epsilon keybinding)

Shift+F5	Repeat search   (Brief keybinding)


Search|Go To Line Number
Search | Go to Line Number1034009

Choose Search|Go to Line Number to display the Go To Line Number dialog box.

Go to Line Number dialog box

This dialog box prompts you for the line number you want to find. The current line number and column number are displayed in the Line and Column Indicator on the status bar of the Code Editor.

When this dialog box first appears, the current line number is in the input box.

Enter New Line Number	Specify the line number of the code you want to go to. To select from a list of previously entered line numbers, click the down arrow next to the input box.


Search|Find Error
Search | Find Error1034010

Choose Search|Find Error to display the Find Error dialog box.

Find Error dialog box

Use this dialog box to specify the address of the most recent run-time error.

Error Address	The address of the most recent run-time error and the error number appears in the runtime error report if it is available.

When you click OK, Delphi recompiles your program and stops at the address location you entered, highlighting the line that caused the run-time error.


Search|BrowseSymbol
Search | Browse Symbol1034011

See also

Choose Search|Browse Symbol to display the Browse Symbol dialog box.

Browse Symbol dialog box

Use this dialog box to open the Object Browser and display the symbol declaration.

Symbol to Find	Enter a symbol name to inspect. To choose from a list of previously entered symbols, click the down arrow. Use the arrow keys to move through the list box.

When you click OK, Delphi opens the ObjectBrowser to display the symbol declaration.

You can go to the source code that defines the symbol or inspect the symbol declaration.


See also1034012

ObjectBrowser window


Regular expressions
Regular expressions1034013

Regular expressions are characters that customize a search string. Delphi recognizes these regular expressions:

Character	Description

 ^	A circumflex at the start of the string matches the start of a line.

 $	A dollar sign at the end of the expression matches the end of a line.

 .	A period matches any character.

 *	An asterisk after a string matches any number of occurrences of that string followed by any characters, including zero characters. For example, bo* matches bot, bo and boo but not b.

 +	A plus sign after a string matches any number of occurrences of that string followed by any characters except zero characters. For example, bo+ matches boo, and booo, but not bo or be.

[ ]	Characters in brackets match any one character that appears in the brackets, but no others. For example [bot] matches b, o, or t.

[^]	A circumflex at the start of the string in brackets means NOT. Hence, [^bot] matches any characters except b, o, or t.

[-]	A hyphen within the brackets signifies a range of characters. For example, [b-o] matches any character from b through o.

{ }	Braces group characters or expressions. Groups can be nested, with a maximum number of 10 groups in a single pattern.

  \  	A backslash before a wildcard character tells the Code Editor to treat that character literally, not as a wildcard. For example, \^ matches ^ and does not look for the start of a line.

Note:	Delphi also supports Brief regular expressions if you are using Brief keystroke mappings.


Brief regular expressions
Brief regular expressions1034014

Use these symbols to produce Brief regular expressions:

 <	A less than at the start of the string matches the start of a line.

 %	A percent sign at the start of the string matches the start of a line.

 $	A dollar sign at the end of the expression matches the end of a line.

 >	A greater than at the end of the expression matches the end of a line.

  ?	A question mark matches any single character.

 @	An at sign after a string matches any number of occurrences of that string followed by any characters, including zero characters. For example, bo@ matches bot, boo, and bo.

 +	A plus sign after a string matches any number of occurrences of that string followed by any characters, except zero characters. For example, bo+ matches bot and boo, but not b or bo.

  |	A vertical bar matches either expression on either side of the vertical bar. For example, bar|car will match either bar or car.

  ~	A tilde matches any single character that is not a member of a set.

[ ]	Characters in brackets match any one character that appears in the brackets, but no others. For example [bot] matches b, o, or t.

[^]	A circumflex at the start of the string in brackets means NOT. Hence, [^bot] matches any characters except b, o, or t.

[-]	A hyphen within the brackets signifies a range of characters. For example, [b-o] matches any character from b through o.

{ }	Braces group characters or expressions. Groups can be nested, with the maximum number of 10 groups in a single pattern.

  \  	A backslash before a wildcard character tells the Borland C++ IDE to treat that character literally, not as a wildcard. For example, \^ matches ^ and does not look for the start of a line.


Tools menu
Tools menu1035001

See also

Use the Tools menu to:

View and change environment settings

Modify the list of programs on the Tools menu

Modify templates and experts.

Create and edit package collections.

Create and modify database tables.

Create and edit images.

Tools menu commands:

Environment Options	Specifies Editor, Browser, and configuration preferences, and customizes the appearance of the Component palette.

Repository	Displays the Object Repository dialog box.

Configure Tools	Displays the Tools Options dialog box. Use this dialog box to add programs to, delete programs from, or edit programs on the Tools menu.

Package Collection Editor	Create and edit package collections. Package collections are a convenient way to bundle packages and associated files for distribution to other developers.

Image Editor	Create and edit resource files, icons, bitmaps, and cursor files for use in Delphi applications.

Database Desktop	Create, view, sort, modify, and query tables in Paradox, dBASE, and SQL formats.


See also1035002

Adding programs to the Tools menu

Tools|Tools


Tools|Options
Tools | Environment Options1035003

Choose Tools|Environment Options to display the Environment Options dialog box. Use the pages of this dialog box to specify Editor, Browser, and configuration preferences, and to customize the way components and pages are arranged on the Component palette.

The pages of the Environment Options dialog box are:

Preferences

Library

Editor Options

Display

Colors

Palette

Browser

Code Insight

To change pages in the dialog box:

Click the tab at the bottom of the dialog box that represents the page you want to use.


Tools|Options - Preferences options
Preferences (Tools | Environment Options)1035004

See also	Environment options

Use the Preferences page of the Enviroment Options dialog box to specify your Delphi configuration preferences.

Desktop contents

Select which desktop settings are saved when you exit Delphi.

Option	When selected

Desktop Only	Saves directory information, open files in the editor, and open windows

Desktop And Symbols	Saves desktop information and browser symbol information from the last successful compile

Autosave options

Specify which files and options are saved automatically by the environment or when you run your program. A check mark means it is enabled.

Check box	When checked

Editor Files	Saves all modified files in the Code Editor when you choose Run|Run, Run|Trace Into, Run|Step Over, Run|Run To Cursor, or when you exit Delphi

Desktop	Saves the arrangement of your desktop when you close a project or exit Delphi. When you later open the same project, all files opened when the project was last closed are opened again regardless of whether they are not used by the project.

Form designer

Set grid preferences that make it easier to design forms.

Option	Effect

Display Grid	Makes the dots that show the form grid visible.

Snap To Grid	Automatically aligns components on the form with the nearest gridline. You cannot place a component "in between" gridlines.

Grid Size X	Sets grid spacing in pixels along the x-axis. Specify a higher number (between 2 and 128) to increase grid spacing.

Grid Size Y	Sets grid spacing in pixels along the y-axis. Specify a higher number (between 2 and 128) to increase grid spacing.

Show Component Captions	Select this option to display component captions.

Debugging

Use the Debugging check boxes to select the debugger you want to use and to enable stepping.

Check box	When checked

Integrated Debugging	Uses the Delphi Integrated Debugger

Step Program Block	Causes the debugger to stop at the first unit initialization that contains debug information

Break On Exception	Stops the application when it reaches an exception and displays the following information:

The exception class

The exception message

The location of the execption

When this option is unchecked, exceptions do not stop the running application. If you are stepping your application, you can step through the exception handlers as if going through the code sequentially.

Compiling and Running

Check box	When checked

Show Compiler Progress	Check to see progress reports while your program compiles.

Warn on package rebuild	Display warning when packages are rebuilt during compile.

Minimize On Run	Minimizes Delphi when you run your application by choosing Run|Run. When you close your application Delphi is restored.

Hide Designers On Run	Hides designer windows, such as the Object Inspector and Form window, while the application is running. The windows reappear when the application closes.


See also1035005

The Delphi Debugger

Creating an exception handler

Form

Project options

Saving projects and individual project files


Tools|Options - Library
Library page (Tools | Environment Options), Global page (Package Options dialog box)1035006

See Also

Use this page to specify directories, compiler, and linker options for all packages. Click the down arrow next to the edit boxes to choose from a list of previously entered symbols.

Map file

Select the type of map file produced, if any. The map file is placed in the directory specfied by DCP Directory, and it has a .MAP extension.

Option	Effect

Off	Does not produce map file.

Segments	Linker produces a map file that includes a list of segments, the program start address, and any warning or error messages produced during the link.

Publics	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, and a list of alphabetically sorted public symbols.

Detailed	Linker produces a map file that includes a list of segments, the program start address, any warning or error messages produced during the link, a list of alphabetically sorted public symbols, and an additional detailed segment map. The detailed segment map includes the segment address, length in bytes, segment name, group, and module information.

Messages	Effect

Show Hints 	Causes the compiler to generate hint messages.

Show Warnings 	Causes the compiler to generate warning messages.

Options	Effect

Compile with debug info	Check to compile the package file with debug information. This will make the resulting file larger, but it does not affect memory requirements or performance.

When you compile a package using debug information, you can use the integrated debugger or Turbo Debugger for Windows to debug the library file.

Directories

DPL output directory	Where the compiler should put the compiled package (.dpl) file.

DCP output directory	Specifies a separate directory to contain the .dcp files.

Library path	Specify search paths where compiler can find the source files for the package. The compiler can find only those files listed in Library Path. If you try to build your package with a file not on the library path, you will receive a compiler error.

Aliases

Unit Aliases	Specify alias names for units that may have changed names or were merged into a single unit. The format is <oldunit>=<newunit>. You can separate multiple aliases with semicolons.


See also

Component palette

Using design-time packages


Options|Environment - Palette
Palette (Tools | Environment Options, Component | Configure Palette)1035007

See also	Environment options

Use the Palette page of the Environment Options dialog box to customize the way the Component palette appears. You can rename, add, or remove, or reorder pages and components.

Pages	Lists the pages in the Component palette, in the order in which they currently appear. You can rearrange these pages or view and rearrange their components in the Components list. The last item in the Pages list is.[All]; when you select [All], the Components list shows components from every page as well as hidden components.

Components 	Lists the components on the currently selected Component-palette page in the Pages list. Components may come from installed packages or they may be component templates created with the Component | Create Component Template command. Components appear in their current order on the palette. You can rearrange components, or move them to a different page, br dragging them. When [All] is selected in the Pages list, you can sort by component name, package, or palette page by clicking on the appropriate column heading.

Use the following buttons when an item is selected in the Pages list.

Move Up / Move Down	To change the position of the selected page, click Move Up or Move Down. You can also drag pages to a new position.

Add 	Click Add to display the Add Page dialog box, where you can create new pages on the Component palette. Once you have created a new Component palette page, you can move components from other pages onto it or add new components to it.

Delete 	To remove the selected page from the palette, click Delete. Before you can delete a page, it must be empty of components.

Rename 	Click Rename to display the Rename Page dialog box, where you can rename the selected page.

Default Pages	Click Default Pages to restore pages to their default order and replace all components on their default pages. This button is available when [All] is selected on the Pages list.

Use the following buttons when an item is selected in the Components list.

Hide / Show	To prevent an installed component from appearing on the Component palette, click Hide. To redisplay a hidden component, select [All] on the Pages list, select the hidden component on the Components list, then click Show.

Delete	To delete a component template, click Delete. This button is available only when a component template is selected.

Move Up / Move Down	To change the position of a component on a page, click Move Up or Move Down. You can also drag components to a new position.


See also1035008

Component palette

Using design-time packages

Adding components to Delphi


Rename Page dialog box
Rename Page dialog box1035009

See also	Options|Environment - Palette

Use this dialog box to specify a new name for a page on the Component Palette.

(You first need to select the page you want to rename from Pages list box on the Palette page of the Options|Environment dialog box.)

To open this dialog box:

Click the Rename button on the Palette page of the Options|Environment dialog box.

Page Name	Enter the new name for the page in the Page Name edit box.When you click OK, the new name is reflected in the Pages list box, but the new name is not reflected in the Component palette until you click OK in the Environment Options dialog box.

To exit this dialog box without changing the page name, choose Cancel.


See also1035010

Adding components to Delphi


Add Page dialog box
Add Page dialog box1035011

See also	Options|Environment - Palette

Use this dialog box to add a new page to the Component palette.

The new page is added to the end of the Pages list. You can change the position of the page using the Palette page of the Options|Environment Options dialog box.

To open this dialog box:

Click the Add button on the Palette page of the Options|Environment dialog box.

Page Name	Enter the new name for the page in the Page Name edit box. When you click OK, the new name is added in the Pages list box, but the new page is not added to the Component palette until you click OK in the Environment Options dialog box.

To exit this dialog box without changing the page name, choose Cancel.


Tools|Options - Browser
Browser (Tools | Environment Options)1035012

See also	Environment options

Use the Browser page of the Enviroment Options dialog box to specify how the ObjectBrowser functions and what symbol information is displayed.

Symbols Type Filters

Specify what symbol information is displayed in the ObjectBrowser. By default, every check box is selected; therefore all symbol information is displayed.

Choose from these symbols:

Constants	Inherited

Types	Virtual only

Functions and Procedures	Private

Variables	Protected

Properties	Public

Published

Initial View

Specify what you want to see when the ObjectBrowser first opens. There are three choices:

Objects

Units

Globals

At any time during a browser session, you can switch views using the ObjectBrowser context menu.

Display

Use these check boxes to select how much detail you want for a symbol and whether or not you want the display sorted:

Option	What it does

Qualified Symbols 	Displays the qualified identifier for a symbol.  When this option is off, only the symbol name is displayed.

Sort Always 	Displays the symbols in alphabetical order by symbol name. When this option is off, the symbols sort by declaration order.

Note:	If both Qualified Symbols and Sort Always are checked, symbols sort by their symbol name, not their object name.

Object Tree

Collapse Nodes	Specify which branches of the object tree hierarchy you want collapsed or expanded when you start the ObjectBrowser.For this setting to take effect, you must be browsing objects.


See also1035013

ObjectBrowser window


Tools|Options - Editor Options
Editor (Tools | Environment Options)1035014

See also	Environment options

Use the Editor page of the Enviroment Options dialog box to customize the behavior of the Delphi editor.

Editor SpeedSetting

Use the Editor SpeedSettings to configure the editor:

Option	Automatically sets

Default Keymapping	Auto Indent Mode, Insert Mode, Smart Tab, Backspace Unindents, Group Undo, Overwrite Blocks, Use Syntax Highlight

IDE Classic	Auto Indent Mode, Insert Mode, Smart Tab, Backspace Unindents, Cursor Through Tabs, Group Undo, Persistent Blocks, Use Syntax Highlight

BRIEF Emulation	Auto Indent Mode, Insert Mode, Smart Tab, Backspace Unindents, Cursor Through Tabs, Cursor Beyond EOF, Keep Trailing Blanks, BRIEF Regular Expressions, Force Cut And Copy Enabled, Use Syntax Highlight

Epsilon Emulation	Auto Indent Mode, Insert Mode, Smart Tab, Backspace Unindents, Cursor Through Tabs, Group Undo, Overwrite Blocks, Use Syntax Highlight

Editor Options check boxes

Use the following editor options to control text handling in the Code Editor. Check the option to enable it.

Check box	When selected

Auto Indent Mode	Positions the cursor under the first nonblank character of the preceding nonblank line when you press Enter.

Insert Mode	Inserts text at the cursor without overwriting existing text. If Insert Mode is disabled, text at the cursor is overwritten. (Use the Ins key to toggle Insert Mode in the Code Editor without changing this default setting.)

Use Tab Character	Inserts tab character. If disabled, inserts space characters. If Smart Tab is enabled, this option is off.

Smart Tab	Tabs to the first non-whitespace character in the preceding line. If Use Tab Character is enabled, this option is off.

Optimal Fill	Begins every autoindented line with the minimum number of characters possible, using tabs and spaces as necessary.

Backspace Unindents	Aligns the insertion point to the previous indentation level (outdents it) when you press Backspace, if the cursor is on the first nonblank character of a line.

Cursor Through Tabs	Enables the arrow keys to move the cursor to the beginning of each tab.

Group Undo	Undoes your last editing command as well as any subsequent editing commands of the same type, if you press Alt+Backspace or choose Edit|Undo.

Cursor Beyond EOF	Positions the cursor beyond the end-of-file character.

Undo After Save	Allows you to retrieve changes after a save.

Keep Trailing Blanks	Keeps any blanks you might have at the end of a line.

BRIEF Regular Expressions	Uses BRIEF regular expressions.

Persistent Blocks	Keeps marked blocks selected even when the cursor is moved, until a new block is selected.

Overwrite Blocks	Replaces a marked block of text with whatever is typed next. If Persistent Blocks is also selected, text you enter is added to the currently selected block.

Double Click Line	Highlights the line when you double-click any character in the line. If disabled, only the selected word is highlighted.

Find Text At Cursor	Places the text at the cursor into the Text To Find list box in the Find Text dialog box when you choose Search|Find. When this option is disabled you must type in the search text, unless the Text To Find list box is blank, in which case the editor still inserts the text at the cursor.

Force Cut And Copy Enabled	Enables Edit|Cut and Edit|Copy, even when there is no text selected.

Use Syntax Highlighting	Enables syntax highlighting. To set highlighting options, use the Colors page.

Other options	When selected

Block Indent 	Specify the number of spaces to indent a marked block. The default is 1; the upper limit is 16. If you enter a value greater than 16, you will receive an error.

Undo Limit 	Specify the number of keystrokes that can be undone. The default value is 32,767 (32K).

Note:	The undo buffer is cleared each time Delphi generates code.

Tab Stops 	Set the character columns that the cursor will move to each time you press Tab. If each successive tab stop is not larger than its predecessor, you will receive an error. The default tab stops are 9 and 17.

Syntax Extensions 	Specify, by extension, which files will display syntax highlighting information. The default extensions are .PAS, .DPR, .DFM, .INC, and .INT.


See also1035015

Working with the Code editor


Tools|Options - Editor Display
Display (Tools | Environment Options)1035016

See also	Environment options

Use the Display page of the Enviroment Options dialog box to select display and font options for the Code Editor. The sample window displays the selected font.

The new settings take effect when you click OK.

Display and File check boxes

Configure the editor's display and choose how it saves files.

Check box	Effect

BRIEF Cursor Shapes	Uses BRIEF cursor shapes.

Create Backup File	Creates a backup file that replaces the first letter of the extension with a tilde (~) when you choose File|Save.

Preserve Line Ends	Preserves end-of-line position.

Zoom To Full Screen	Maximizes the Code Editor to fill the entire screen. When this option is off, the Code Editor does not cover the Delphi main window when maximized.

Keystroke Mapping

Enables you to quickly switch key bindings.

Mapping	Effect

Default	Uses key bindings that match CUA mappings (default)

Classic	Uses key bindings that match Borland Classic editor keystrokes

Brief	Uses key bindings that emulate most of the standard BRIEF keystrokes

Epsilon	Uses key bindings that emulate a large part of the Epsilon editor

Visible Right Margin 	Check to display a line at the right margin of the Code Editor.

Right Margin 	Set the right margin of the Code Editor. The default is 80 characters. The valid range is 0 to 1024. If you enter a value larger than 1024, an error message appears.

Visible gutter 	Check to display the gutter on the left edge of the Code Editor.

Gutter width 	Set the width of the gutter, default is 32.

Editor Font 	Select a font type from the available screen fonts installed on your system (shown in the list). The Code Editor displays and uses only monospaced screen fonts, such as Courier. Sample text is displayed below the combo box.

Size 	Select a font size from the predefined font sizes associated with the font you selected in the Font list box. Sample text is displayed below the combo box.

Sample text 	Displays a sample of the select editor font and size.


See also1035017

Code Editor

Working with the Code editor


Tools|Options - Editor Colors
Colors (Tools | Environment Options)1035018

See also	Environment options

Use the Colors page of the Enviroment Options dialog box to specify how the different elements of your code appear in the Code Editor.

You can specify foreground and background colors for anything listed in the Element list box. The sample Code Editor shows how your settings will appear in the Delphi Code Editor.

Color SpeedSettings

Enables you to quickly configure the Code Editor display using predefined color combinations. The sample Code Editor shows how your settings will appear in the Delphi Code Editor.

Element	Specifies syntax highlighting for a particular code element. You can choose from the Element list or click the element in the sample Code Editor.

Color 	Sets the foreground (FG) and background (BG) colors for the selected code element.

To select a color using the mouse, choose one of the following methods:

Click a color to select it as the foreground color.

Right-click a color to select it as the background color.

If you choose the same color for the foreground and the background, it is marked as FB. (This is not recommended.)

To select the color using the keyboard:

1.	Use the arrow keys to highlight a color.

2.	Press F to select it as the foreground color, or B to select it as the background color.

Text Attributes checkboxes Specify format attributes for the code element. The attribute options Delphi supports are bold, italic and underline.

Use defaults for 	Display the code element using default Windows system colors (foreground, background, or both). Unchecking either option restores the previously selected color or, if no color has been previously selected, sets the code element to the Windows system color.


See also1035019

Code Editor

Using syntax highlighting


Using syntax highlighting
Using syntax highlighting1035020

See also

Syntax highlighting changes the colors and attributes of your text in the code editor, making it easier to quickly identify parts of your code.

To enable syntax highlighting:

On the Editor Options page of the Tools|Environment Options dialog box, check the Use Syntax Highlight option.

To change the syntax highlighting colors for elements of your code:

Use the Editor Colors page of the Tools|Environment Options dialog box.


See also1035021

Code Editor


Tools|Tools
Tools| Configure Tools1035022

Choose Tools|Tools to display the Tools Options dialog box.

Use the Tools Options dialog box to add, delete, or edit programs on the Tools menu.


Tools Options dialog box
Tools Options dialog box1035023

Choose Tools| Configure Tools to open the Tools Options dialog box.

Use this dialog box to add programs to, delete programs from, or edit programs on the Tools menu.

Tools Options dialog box

Tools	Lists the programs currently installed on the Tools menu.

Add	Click Add to display the Tool PropertiesToolPropertiesDB dialog box, where you can specify a menu name, a path, and startup parameters for the program.

Delete	Click Delete to remove the currently selected program from the Tools menu.

Edit	Click Edit to display the Tool Properties dialog box, where you can edit the menu name, the path, or the startup parameters for the currently selected program.

Arrow	Use the arrow buttons to rearrange the programs in the list. The programs appear on the Tools menu in the same order they are listed in the Tool Options dialog box.

To add a program to the tools menu:

Choose Add. Delphi displays the Tool Properties dialog box, where you specify information about the application you are adding.

To delete a program from the tools menu:

Select the program to delete, and choose Delete. Delphi prompts you to confirm the deletion.

To change a program on the tools menu:

Select the program to change, and choose Edit. Delphi displays the Tool Properties dialog box with information for the selected program.


See also1035024

Adding programs to the Tools menu


Tool Properties dialog box
Tool Properties dialog box1035025

Use the Tool Properties dialog box to enter or edit the properties for a program listed on the Tools menu.

To display the Tool Properties dialog box:

Click Add or Edit in the Tool Options dialog box.

Tool Properties	Description

Title 	Enter a name for the program you are adding. This name will appear on the Tools menu. To add an accelerator to the menu command, precede that letter with an ampersand (&). If you specify a duplicate accelerator, Delphi displays a red asterisk (*) next to the program names in the Tool Options dialog box.

Program	Enter the location of the program you are adding. Include the full path to the program.  To search your drives and directories to locate the path and file name for the program, click the Browse button

Working Dir	Specify the working directory for the program. Delphi specifies a default working directory when you select the program name in the Program Edit Box. You can change the directory path if needed.

Parameters	Enter parameters to pass to the program at startup. For example, you might want to pass a file name when the program launches. Type the parameters or use the Macros button to supply startup parameters. You can specify multiple parameters and macros.

Macros	Click Macros to expand the Tool Properties dialog box to display a list of available macros.  You can use these macros to supply startup parameters for your application.

Browse	Click Browse to select the program name for the Program edit box. When you click Browse, the Select Transfer Item dialog box opens.

To add a macro to the list of parameters:

Select a macro from the list and click Insert.


Transfer macros
Transfer macros1035026

Use transfer macros to supply startup parameters to a program on the Tools menu.

To display the macros:

Click the Macros button on the Tool Properties dialog box.

Macro	Description

$COL	Expands to the column number of the cursor in the active Code Editor window.

For example, if the cursor is in column 50, at startup Delphi passes "50" to the program.

$ROW	Expands to the row number of the cursor in the active Code Editor window.

For example, if the cursor is in row 8, at startup Delphi passes "8" to the program.

$CURTOKEN	Expands to the word at the cursor in the active Code Editor window.

For example, if the cursor is on the word Token, at startup Delphi passes "Token" to the program.

$PATH	Expands to the directory portion of a parameter you specify. When you insert the $PATH macro, Delphi inserts $PATH() and you specify a parameter within the parentheses.

For example, if you specify $PATH($EDNAME), at startup Delphi passes the path for the file in the active Code Editor window to the program.

$NAME	Expands to the file name portion of a parameter you specify. When you insert the $NAME macro, Delphi inserts $NAME() and you specify a parameter within the parentheses.

For example, if you specify $NAME($EDNAME), at startup Delphi passes the file name for the file in the active Code Editor window to the program.

$EXT	Expands to the file extension portion of a parameter you specify. When you insert the $EXT macro, Delphi inserts $EXT() and you specify a parameter within the parentheses.

For example, if you specify $EXT($EDNAME), at startup Delphi passes the file extension for the file in the active Code Editor window to the program.

$EDNAME	Expands to the full file name of the active Code Editor window.

For example, if you are editing the file C:\PROJ1\UNIT1.PAS, at startup Delphi passes "C:\PROJ1\UNIT1.PAS" to the program.

$EXENAME	Expands to the full file name of the current project executable.

For example, if you are working on the project PROJECT1 in C:\PROJ1, at startup Delphi passes "C:\PROJ1\PROJECT1.EXE" to the program.

$PARAMS	Expands to the command-line parameters specified in the Run Parameters dialog box.

$PROMPT	Prompts you for parameters at startup. When you insert the $PROMPT macro, Delphi inserts $PROMPT() and you specify a default parameter within the parentheses.

$SAVE	Saves the active file in the Code Editor.

$SAVEALL	Saves the current project.

$TDW	Sets up your environment for running Turbo Debugger. For example, this macro saves your project, ensures that your project is compiled with debug info turned on, and recompiles your project if it is not compiled with debug info turned on. Be sure to use this macro if you add Turbo Debugger to the Tools menu.


Select Transfer Item dialog box
Select Transfer Item dialog box1035027

Use the Select Transfer Item dialog box to search drives and directories for a program to add to the Tools menu.

To locate a transfer item:

Click the Browse button on the Tool Properties dialog box.

File Name	Enter the name of the file you want to load, or enter wildcards to use as filters in the Files list box.

Files	Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type	Choose the type of file you want to open. The default file types are .EXE, .COM, and .PIF files. All files in the current directory of the selected type appear in the Files list box.

Directories	Select the directory whose contents you want to view. Files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.


MTools Repository
Tools | Repository1035028

Choose Tools|Repository to display the Object Repository dialog box. Use the Object Repository dialog box to add, delete, and rename pages in the Object Repository. In addition, you can edit and delete Object Repository items.  You can also specify template and expert options for forms and projects

Pages included on the Object Repository correspond to the User Defined pages in the New Items dialog box displayed by File | New� The objects listed are available from the New Items dialog box.

See also

Object Repository dialog box

About the Object Repository


Object Repository dialog box
Object Repository dialog box1035029

Choose Tools|Repository to display the Object Repository dialog box.

Object Repository Options

The settings in the Object Repository Options dialog box affect the behavior of Delphi when you begin a new project or create a new form in an open project. When you select an item in the Objects list box, the appropriate options become available at the bottom of the Objects list box. Depending on the item you select, one or more of the options listed below become available.

New form

Main form

You have the option to override these defaults by choosing File|New and selecting from the New Items dialog box.

By default, opening a new project displays a blank form. You can change this default behavior by changing Object Repository options. For more information see Customizing the Object Repository.

Object Repository
Options	Description

Pages	This list box displays the pages in the Object Repository. When you select a page, the items on that page appear in the Objects list box. Select [Object Repository] to view all items in the Object Repository. The pages in the Object Repository correspond to the user defined pages in the New Items dialog box.  Select File | New� to display the New Items dialog box.

Objects	The Objects list box displays the items on the currently selected page of the Object Repository.

Add Page button	To add a new blank page, click the Add Page button. The Add Page  dialog box appears. Type the name of the page you want to add and click OK.

Delete Page button	To remove an empty page from the Object Repository, in the Pages list box, select the name of the page you want to delete and click the Delete Page button

Rename Page button	To rename an item in the Object Repository, in the Pages list box, select the name of the page you want to rename and click the Rename Page button. The Rename PageRenamePageDialogBox dialog box appears. Type the name of the page you want to rename and click OK. The renamed page appears in the Pages list box.

Edit Object	To edit the properties of items in the Object Repository, from the Objects list box, select the item you want to edit and click the Edit Object button. The Edit Object InfoEditObjectInfoDialogBox dialog box appears. Edit the information as desired and click OK.

Delete Object	Use the Delete Object button to remove the selected object from the Object Repository page.

Up/Down arrows	To change the position of the selected page, click the up arrow or the down arrow. You can also move pages by using a drag-and-drop operation.

There are three ways to add an object to a page:

Right click in a form, select Add to repository from the speed menu.

Select Project | Add to repository.

Drag an object listed in the Object column to a page listed in the Page column of the Object Repository.


Add Page dialog box
Add Page dialog box1035030

Use the Add Page dialog box to add a page to the Object Repository. You access the Add Page dialog box from the Object Repository dialog box.

Page name

Type the name of the new page into the Page name text box.


Rename Page dialog box
Rename Page dialog box1035031

Use the Rename Page dialog box to rename a page in the Object Repository. You access the Rename Page dialog box from the Object Repository dialog box.

Page name	Type the new name of the page into the Page name text box.


Edit Object Info dialog box
Edit Object Info dialog box1035032

Use the Edit Object Info dialog box to edit information of Object Repository items.

Options	Description

Title 	Displays the title of the selected item.

Description	Displays the description of the selected item.

Page	Displays the current page containing the selected item. To change the page on which the item appears, select a different page from the Page drop-down list.

Author	Displays the name of the Author of the selected item.

Browse button	The icon of the selected item is displayed to the left of the Browse button. Use the Browse button to select a different icon.

To view the item description:

1.	From the File menu select New.

2.	Select an item in the New Items dialog box.

3.	Right-click the mouse.

4.	Select View Details from the context menu.

The item description appears in the Description column.


Adding programs to the Tools menu
Adding programs to the Tools menu1035033

See also

The commands on the Tools menu transfer execution to an external application. You can add programs to, delete programs from, or edit programs on the Tools menu.

To add a program to the tools menu:

1.	Choose Tools| Configure Tools.

Delphi displays the Tool Options dialog box, which lists the programs currently on the Tools menu.

2.	Choose Add.

Delphi displays the Tool Properties dialog box.

3.	Specify a title for the program. The title you specify will be listed on the Tools menu.

4.	Specify the program file or choose Browse to select it from a list.

5.	Specify the working directory for the program, if necessary.

6.	Specify startup parameters for the program, if necessary. You can type the parameters or use the Macros button to supply startup parameters. You can specify multiple parameters and macros.

7.	Choose OK.

Delphi closes the Tool Properties dialog box. The new program is on the Tools list in the Tool Options dialog box.

8.	Choose Close.

Delphi closes the Tool Options dialog box. The new program is on the Tools menu.


See also1035034

Tool Properties dialog box

Transfer macros


About Code Insight
About Code Insight1035035

Code Insight enhancements to the code editor display context sensitive pop-up windows within the code file.

To enable and configure Code Insight features, use the Environment Options dialog box.  Select Tools|Environment Options� and select the Code Insight page.

Code Insight provides four tools:

Code Completion

When enabled, the Code Completion dialog box is displayed after you enter a class name followed by a period. The list of properties, methods and events appropriate to the class are displayed. Select the item to be entered in your code.

When you enter an assignment statement and press <ctrl><space_bar>, the list of arguments valid for the variable is displayed. Select an argument to be entered in your code. Similarly, you can bring up a list of arguments when typing a procedure, function, or method call and need to add an argument, or when you are typing in an array property (not a genuine array) and you need to type an index expression.

Code Parameters

View the required arguments for a method as you enter it into your code.

When the Code Parameters feature is enabled, a list box is displayed when you enter a method call followed by the opening parenthesis. The syntax for the arguments to the method is displayed.

Code Templates

A set of templates is available to insert common programming statements into your code. Templates can be edited and added.

While working in the code editor, press <ctrl> j to display the code templates defined.

Tooltip Expression Evaluation

To make it easy to see the value of a variable at any point, enable Tooltip Expression Evaluation.  (To enable Tooltip Expression Evaluation, use the Code Insight dialog box.)  When your are compiling using debug mode and the compile process is stopped, you can point to a variable to display the value of the variable at that point.

When optimization is enabled for the compiler, you might sometimes see a blinking bubble that says "Evaluating" rather than the value. Disable optimization when debugging. (Choose Project | Options, select the Compiler page, and uncheck the Optimization box under Code Generation.)


Code insight dialog box
Code insight dialog box1035036

See also

Use the Code Insight dialog box to configure Code Insight options. Code Insight tools are available while you are working in the code editor.

Automatic Feature	When Enabled

Code Completion	Enter a class name followed by a period in a code file. The list of properties, methods and events appropriate to the class will be displayed. You can then select the item to be entered in your code.

Enter an assignment statement and press <ctrl> <spacebar>. A list of arguments that are valid for the variable is displayed. Select an argument to be entered in your code.

Code Parameters	View the syntax of a Delphi method as you enter it into your code.

Tooltip Expression Evaluation	When the compiler is stopped during debug, you can view the value of a variable by pointing to it with your cursor.

Code Completion Delay	Set the duration of the pause before a Code Insight dialog box is displayed.

Code Templates	Available templates are listed by name with a short description. Click a template name to display the code that will be entered in your file when that template is selected. Code displayed in the code window can be edited.

Templates	The Templates box includes a name and short description for each template.

Code	The code box displays the code that will be inserted into a file when the template is selected. The code displayed can be edited.

To edit the name and description:
Select the name you want to edit. Click the Edit button. Edit the name and description fields as needed and click OK.

To edit a template:
When a name is selected, the code to be inserted in the file when the template is selected is displayed in the code window. Use the mouse to move the cursor to the code window and edit the text as needed.

To define the insertion point for a template:
Place a vertical bar in the code statement to define the point to begin insertion when the template is inserted in a code file. The cursor will be placed in the spot defined by the vertical bar.

To add a template:
Click Add.. After entering a Name and Description in the dialog box displayed, click OK. The cursor will move to the code window for you to define the code that will be entered in a file when the template is selected.

To delete a template:
Select the name of the template you want to delete. Click Delete.


See also
See also1035037

About Code Insight


Code completion
Code completion 1035038

The dialog box lists the valid properties, methods, and events for the class entered.

Arguments that are valid for assignment to the variable entered are listed. Select an item from the list followed by three ellipses (�) to open a second list of related arguments compatible with the variable entered in the assignment statement.

Select an item to be entered in your code file in either of two ways:

Scroll through the list if necessary and double-click the item.

Type until the characters entered refer to the entry in the list you wish to include and press return.

Preferences for Code Completion are configured by selecting Tools|Environment Options to open the Environment Options dialog box. Select Code Insight page.


Code template
Code template 1035039

The templates defined for your installation are listed. Select an item to be entered in your code file in either of two ways:

Use the scroll bar as necessary then double click on the template you want to insert in your code.

Type the name of the template until the characters entered refer to the entry in the list you wish to include. Press return.

Code Templates are defined using the Environment Options dialog box. Select Tools|Environment Options and select the Code Insight page.


表示メニュー
表示メニュー1036001

［表示］メニューのコマンドは Delphi 環境の各種の要素を表示したり隠したり，また統合デバッガに所属するウィンドウを開くために使います。

プロジェクトマネージャ(P)	プロジェクトマネージャを表示します。

プロジェクトソース(J)	コードエディタ内にプロジェクトファイルを表示します。

オブジェクトインスペクタ(O)	オブジェクトインスペクタを表示します。

位置合わせパレット(A)	位置合わせパレットを表示します。

ブラウザ(R)	オブジェクトブラウザを表示します。

ブレークポイント(B)	［ブレークポイント一覧］ダイアログボックスを表示します。

呼び出し履歴(C)	［呼び出し履歴］ダイアログボックスを表示します。

監視式(W)	［監視式一覧］ダイアログボックスを表示します。

スレッド(H)	［スレッドの状態］ボックスを表示します。

モジュール(M)	［モジュール］ウィンドウを表示します。

コンポーネント一覧(L)	［コンポーネント］ダイアログボックスを表示します。

ウィンドウの一覧(I)	開いているウィンドウのリストを表示します。

フォーム/ユニット切り替え(G)	フォームとそのユニットウィンドウの間を切り替えます。

ユニット(U)	［ユニットの表示］ダイアログボックスを表示します。

フォーム(F)	［フォームの表示］ダイアログボックスを表示します。

タイプライブラリ(T)	［Type Library］エディタウィンドウを表示します。

別の編集ウィンドウを開く(E)	新しいコードエディタを起動します。

スピードバー(S)	スピードバーを隠すか表示します。

コンポーネントパレット(N)	コンポーネントパレットを隠すか表示します。


表示(V)｜プロジェクトマネージャ(P)
表示(V)｜プロジェクトマネージャ(P)1036002

［表示(V)｜プロジェクトマネージャ(P)］を選択するとプロジェクトマネージャが開きます。プロジェクトマネージャがすでに開いている場合はそれがアクティブウィンドウになります。

プロジェクトマネージャウィンドウはプロジェクトのファイル間の移動に使います。さらに，ファイルを現在のプロジェクトへ追加，削除，保存，およびコピーするためにも使います。プロジェクトマネージャには現在のプロジェクトで使われているすべてのユニットとそれらの関連フォームのリストがパス情報と一緒に示されます。

メモ:	ユニットは現在オープンされていなくてもプロジェクトマネージャの中に一覧表示されます。

プロジェクトマネージャはデスクトップ上の任意の場所へ配置できます。


表示(V)｜プロジェクトソース(J)
表示(V)｜プロジェクトソース(J)1036003

参照

［表示(V)｜プロジェクトソース(J)］を選択すると，開いているプロジェクトのプロジェクトファイルがコードエディタのアクティブページになります。このコマンドを選択した時点でプロジェクトファイルが開いていない場合，プロジェクトファイルが自動的に開きます。


参照1036004

プロジェクトファイル

プロジェクトマネージャ


表示(V)｜オブジェクトインスペクタ(O)
表示(V)｜オブジェクトインスペクタ(O)1036005

参照

オブジェクトインスペクタをすでに閉じている場合，このコマンドを選択するとオブジェクトインスペクタが再び開きます。［表示(V)｜オブジェクトインスペクタ(O)］を選択すると，オブジェクトインスペクタと直前のアクティブフォームまたはコードエディタファイルが切り替わります。

オブジェクトインスペクタを使ってプロパティの値とイベントハンドラリンクを編集します。


参照
参照1036006

オブジェクトインスペクタのプロパティエディタについて


表示(V)｜位置合わせパレット(A)
表示(V)｜位置合わせパレット(A)1036007

参照

［表示(V)｜位置合わせパレット(A)］を選択すると位置合わせパレットが表示され，これを使ってコンポーネントの位置をフォームやほかのコンポーネントに揃えることができます。

メモ:	［位置合わせ］ダイアログボックスを使ってもコンポーネントの位置を揃えることができます。


位置合わせパレット
位置合わせパレット1036008

参照

位置合わせパレットはコンポーネントの位置をフォームやほかのコンポーネントに揃えるために使います。

位置合わせパレットには各ボタンにツールヘルプがあります。

アイコン	効果

	選択した複数のコンポーネントを最初に選択したコンポーネントの左端に揃える (コンポーネントが 1 つだけの場合は除く)
	選択した複数のコンポーネントを水平方向に移動し，それぞれの中心を最初に選択したコンポーネントに揃える (コンポーネントが 1 つだけの場合は除く)
	選択した 1 つ以上のコンポーネントをフォームの水平方向の中心に揃える
	中央のコンポーネントとその外側のコンポーネントの距離がそれぞれ等しくなるように，選択した 3 つ以上のコンポーネントを水平方向に揃える
	選択した複数のコンポーネントを最初に選択したコンポーネントの右端に揃える (コンポーネントが 1 つだけの場合は除く)
	選択した複数のコンポーネントを最初に選択したコンポーネントの上端に揃える (コンポーネントが 1 つだけの場合は除く)
	選択した複数のコンポーネントを垂直方向に移動し，それぞれの中心を最初に選択したコンポーネントに揃える (コンポーネントが 1 つだけの場合は除く)
	選択した 1 つ以上のコンポーネントをフォームの垂直方向の中心に揃える
	中央のコンポーネントとその外側のコンポーネントの距離がそれぞれ等しくなるように，選択した 3 つ以上のコンポーネントを垂直方向に揃える
	選択した複数のコンポーネントを最初に選択したコンポーネントの下端に揃える (コンポーネントが 1 つだけの場合は除く)
位置合わせパレット上にある特定のボタンの動作がよくわからない場合は，そのボタンをクリックするとボタン上のアイコンが変化し，選択したコンポーネントの位置合わせ方法が示されます。ボタンの位置合わせを選択対象に適用するにはそのボタンを離します。ボタンをクリックして押さえた後で位置合わせを取り消すには，マウスボタンを離す前にマウスをパレットの外へドラッグします。

メモ:	［位置合わせ］ダイアログボックスを使ってもコンポーネントの位置合わせができます。


参照1036009

コンポーネントの位置合わせ

フォーム内のコンポーネントの選択

コンポーネントの位置合わせ


表示(V)｜監視式(W)
表示(V)｜監視式(W)1036010

［表示(V)｜監視式(W)］を選択すると監視式一覧ウィンドウが開きます。

監視式ウィンドウには現在設定されているすべての監視式が表示されます。

このウィンドウをデバッグセッション中に開いておくと，重要な変数の値がプログラムの実行につれて更新される様子を監視できます。


表示(V)｜スレッド(H)
表示(V)｜スレッド(H)1036011

［表示(V)｜スレッド(H)］を選択すると［スレッドの状態］ステータスボックスが表示されます。

このステータスボックスを使うと，デバッグ中のアプリケーション内で現在実行されているすべてのスレッドの状態を見ることができます。


スレッドの状態ステータスボックス
スレッドの状態ステータスボックス1036012

［表示(V)｜スレッド(H)］を選択すると［スレッドの状態］ステータスボックスが表示されます。

このステータスボックスを使うと，デバッグ中のアプリケーション内で現在実行されているすべてのスレッドの状態を見ることができます。

デバッグイベント (ブレークポイント，例外，一時停止) が発生したとき，スレッドステータスビューは実行中の各スレッドの状態を示します。ローカルメニューを使うと，ユーザーが別のスレッドをカレントにすることができます。スレッドがカレントとしてマークされると，次のステップまたは実行操作はそのスレッドに対する相対になります。

［スレッドの状態］ステータスボックス

［スレッド ID］	OS が割り当てたスレッド ID が表示されます。

［状況］	スレッドステートは［走行中］または［停止］です。

［位置］	ソースコード上の位置が表示されます。ソースコード上の位置がわからない場合はアドレスが表示されます。

［状態］

スレッドステータスとして次のいずれかが表示されます。

ブレークポイント	このスレッドはブレークポイントによって停止した

フォルト	このスレッドはプロセッサ例外によって停止した

不明	このスレッドはカレントスレッドではないのでステータスは不明

ステップ	直前のステップコマンドは問題なく実行された


表示(V)｜モジュール(M)
表示(V)｜モジュール(M)1036013

［表示(V)｜モジュール(M)］を選択すると現在のプロジェクトの実行時にメモリにロードされたモジュールのリストが表示されます。［モジュール］ウィンドウには各モジュールの名前，その実行時イメージ基底アドレス，およびモジュールのロード元の場所を示すパスが表示されます。

ここでの「モジュール」とは一般に，現在のプロジェクトが実行時に必要とする DLL またはパッケージを意味します。通常，このウィンドウを開くのはプロジェクトのコンパイル後でそのデバッグ中のときです。また，必要なモジュールそれぞれに基本選択イメージ基底オフセットを指定することによってロード時間を改善するために最適化を行うときにも役立ちます。

実行時イメージ基底アドレスはモジュールが実際にロードされる場所の 16 進メモリオフセットであり，［プロジェクトオプション］ウィンドウで指定した基本選択イメージ基底アドレスとは異なることに注意してください。


表示(V)｜ブレークポイント(B)
表示(V)｜ブレークポイント(B)1036014

［表示(V)｜ブレークポイント(B)］を選択するとブレークポイント一覧ウィンドウが開きます。

ブレークポイントウィンドウには現在設定されているすべてのブレークポイントが一覧表示されます。

個々のブレークポイントリストには次の情報が示されます。

そのブレークポイントが設定されているファイル

そのブレークポイントの行番号

そのブレークポイントに関連した条件

そのブレークポイントに関連したパスカウント


表示(V)｜呼び出し履歴(C)
表示(V)｜呼び出し履歴(C)1036015

［表示(V)｜呼び出し履歴(C)］を選択すると呼び出し履歴ウィンドウが開きます。

呼び出し履歴ウィンドウにはプログラムが呼び出したルーチンの現在のシーケンスが一覧表示されます。このリストではもっとも新しく呼び出されたルーチンがウィンドウの一番上に示され，前のルーチン呼び出しほど下に表示されます。

呼び出し履歴ウィンドウには個々のエントリごとにプロシージャ名とそのプロシージャへ渡されたパラメータの値が表示されます。


表示(V)｜ブラウザ(R)
表示(V)｜ブラウザ(R)1036016

参照

［表示(V)｜ブラウザ(R)］を選択するとオブジェクトブラウザウィンドウが開きます。

オブジェクトブラウザを使うと，アプリケーション内で使っているオブジェクト，ユニット，クラス階層，メソッドをビジュアルに調べることができます。

メモ：	［ブラウザ(R)］コマンドが使えない場合はプログラムをコンパイルしてからオブジェクトブラウザを開きます。


参照1036017

オブジェクトブラウザウィンドウ


表示(V)｜コンポーネント一覧(L)
表示(V)｜コンポーネント一覧(L)1036018

参照

［表示(V)｜コンポーネント一覧(L)］を選択するとコンポーネントウィンドウが表示されます。

コンポーネントウィンドウ

このウィンドウはマウスまたはキーボードを使ってコンポーネントをフォームへ追加するために使います。

オプション	説明

［名前で検索(S)］	追加したいコンポーネントの名前を入力する。このリストボックスはインクリメンタルサーチをするので，カーソルは入力した文字列が入っている最初のコンポーネントまで移動する

コンポーネントリストボックス	追加したいコンポーネントを選択する。コンポーネントはアルファベット順に一覧表示され，左側にボタン表現が示される

コンポーネントを選択すると，その名前が［名前で検索(S)］編集ボックスに表示される

［フォームに追加(A)］	［フォームに追加(A)］をクリックすると，選択したコンポーネントのインスタンスがフォームの中央に置かれる。［フォームに追加(A)］は〔Enter〕を押せば選択できる

コンポーネントリストボックスで選択したコンポーネントを追加するには

次のいずれかの操作を行います。

〔Enter〕を押す

コンポーネント名をダブルクリックする

［フォームに追加(A)］ボタンをクリックする

メモ:	キーボードを使ってフォームにコンポーネントを追加した場合，そのコンポーネントはデフォルトのコンポーネントサイズでフォームの中央に追加されます。ただし，コンテナコンポーネント (グループボックスまたはパネルなど) を選択した場合は除きます。

コンテナコンポーネントを選択した場合，追加コンポーネントはそのコンテナの中央に置かれます。コンテナの中にコンポーネントを追加するには，［フォームに追加(A)］を選択する前にコンテナを選択しておかなくてはなりません。


参照1036019

キーボードを使ったコンポーネントの追加


表示(V)｜フォーム/ユニット切り替え(G)
表示(V)｜フォーム/ユニット切り替え(G)1036020

参照

［表示(V)｜フォーム/ユニット切り替え(G)］を選択すると現在のフォームまたはそのユニットファイルが表示されます。

次の方法でも同じことができます。

ツールバーで［フォーム/ユニット切り替え］ボタンを選択する

プロジェクトマネージャのコンテキストメニューで［ユニットの表示(U)］または［フォームの表示(F)］を選択する


参照1036021

プロジェクトの内容の表示と操作

表示(V)｜フォーム(F)

表示(V)｜ユニット(U)


表示(V)｜ユニット(U)
表示(V)｜ユニット(U)1036022

参照

［表示(V)｜ユニット(U)］を選択すると［ユニットの表示］ダイアログボックスが表示されます。

［ユニットの表示］ダイアログボックス

このダイアログボックスは現在のプロジェクトのプロジェクトファイルまたは任意のユニットを表示するために使います。ユニットを選択すると，そのユニットがコードエディタ内でアクティブページになります。

オープンしたいユニットが現在オープンされていない場合，そのユニットが自動的にオープンされます。

次の方法でも同じことができます。

スピードバーで［ユニットリスト表示］ボタンを選択する

プロジェクトマネージャのコンテキストメニューで［ユニットの表示(U)］を選択する


参照1036023

プロジェクトファイル

ユニットファイル

プロジェクトの内容の表示と操作


表示(V)｜フォーム(F)
表示(V)｜フォーム(F)1036024

参照

［表示(V)｜フォーム(F)］を選択すると［フォームの表示］ダイアログボックスが表示されます。

［フォームの表示］ダイアログボックス

このダイアログボックスは現在のプロジェクト内の任意のフォームを表示するために使います。フォームを選択するとそのフォームがアクティブフォームになり，関連ユニットがコードエディタ内でアクティブモジュールになります。

フォームを選択した時点で関連ユニットがオープンされていない場合，そのユニットが自動的にオープンされます。

次の方法でも同じことができます。

スピードバーで［フォームリスト表示］ボタンを選択する

プロジェクトマネージャのコンテキストメニューで［フォームの表示(F)］を選択する


参照1036025

フォーム

プロジェクトの内容の表示と操作ユーザーインターフェースの作成


表示(V)｜ウィンドウの一覧(I)
表示(V)｜ウィンドウの一覧(I)1036026

［表示(V)｜ウィンドウの一覧(I)］を選択すると［ウィンドウの一覧］ダイアログボックスが表示されます。

［ウィンドウの一覧］ダイアログボックス

このダイアログボックスは非アクティブな Delphi ウィンドウをアクティブにするために使います。多くのウィンドウを開いている場合，これが特定のウィンドウを見つけるもっとも簡単な方法です。［ウィンドウリスト］ダイアログボックスには開いているすべての Delphi ウィンドウが表示されます。

ウィンドウを選択するには

次のいずれかの操作を行います。

ウィンドウ名をダブルクリックする

ウィンドウ名を選択して［OK］をクリックする


表示(V)｜別の編集ウィンドウを開く(E)
表示(V)｜別の編集ウィンドウを開く(E)1036027

［表示(V)｜別の編集ウィンドウを開く(E)］を選択すると，コードエディタのアクティブページをコピーした新しいコードエディタが開きます。

コピー元とコピーのどちらに変更を加えても，その変更は両方のファイルに反映されます。

ウィンドウを区別するため，元のウィンドウのキャプションには末尾に 1 が付き，最初のコピーは 2，2 番目のコピーは 3 などとなります。


表示(V)｜スピードバー(S)
表示(V)｜スピードバー(S)1036028

［表示(V)｜スピードバー(S)］を選択すると，スピードバーが表示されるか隠されます。

このコマンドにチェックマークが付いている場合，スピードバーが表示されています。

スピードバーのコンテキストメニューで［隠す(H)］を選択してもスピードバーを隠せます。


表示(V)｜コンポーネントパレット(N)
表示(V)｜コンポーネントパレット(N)1036029

［表示(V)｜コンポーネントパレット(N)］を選択すると，コンポーネントパレット が表示されるか隠されます。

このコマンドにチェックマークが付いている場合，コンポーネントパレットが表示されています。

コンポーネントパレットのコンテキストメニューで［隠す(H)］を選択してもコンポーネントパレットを隠せます。


表示(V)｜タイプライブラリ(T)
表示(V)｜タイプライブラリ(T)1036030

参照

タイプライブラリエディタを使うと ActiveX コントロール，ActiveX サーバー，その他の COM オブジェクトの型情報を検査，および作成できます。型情報はタイプライブラリ (.TLB) ファイルに入れてスタンドアロンでオブジェクトとともに提供することも，またリソースとして EXE または OCX に統合することもできます。タイプライブラリをアプリケーションまたは OCX に入れると，その中に入っているオブジェクトに関する情報をほかのアプリケーションやプログラミングツールが利用できるようになります。

ウィザードを使って Delphi コンポーネントを ActiveX コントロールに変換する場合，タイプライブラリは自動生成されます。コントロールの構築時に ActiveX コントロールウィザードがタイプライブラリをリソースとして OCX に自動的にコンパイルします。ウィザードを使うときに［Type Library］ダイアログボックスを使う必要はありませんが，ウィザードが作成した型情報をこのダイアログボックスで検査したり変更することもできます。

通常，タイプライブラリエディタを使って型情報ファイルを作成する必要があるのは，ActiveX サーバーなどの COM オブジェクトにカスタム機能を追加してこの機能をクライアントにエクスポーズしたい場合だけです。ウィザードは Delphi コンポーネントの組み込み機能をサポートする目的だけでタイプライブラリを作成するので，クライアントに提供したい追加のメソッド，イベント，プロパティがある場合は，オブジェクトのタイプライブラリファイルに追加しなければなりません。

タイプライブラリについての概要と，タイプライブラリエディタでのタイプライブラリの使い方に関するトピックへのリンクについては，タイプライブラリについてを参照してください。

詳しい扱い方については，『Delphi 開発者ガイド』のオンライン版で特に次のトピックを参照してください。

タイプライブラリの操作

OLE と ActiveX の概要

タイプライブラリエディタの主な要素は次のとおりです。

ツールバー
ここにあるボタンは新しい情報型のインスタンスを現在のタイプライブラリに追加します。ボタンをクリックすると，そのアイコンがオブジェクトリストペインに追加されます。

エラーログペイン

オブジェクトリストペイン
現在のタイプライブラリにある情報型の各インスタンスは，右側のオブジェクトリストにユニークなアイコンで示されます。アイコンを選択して，右側の情報ペインに表示されるデータページを確認します。

情報ペイン。オブジェクトリストペインで選択した各オブジェクトについて，このペインは［Attributes］，［Uses］，［Members］のタブページで次の情報を表示する

タイプライブラリ情報

列挙型情報

インターフェースとオブジェクトの情報

インターフェースのプロパティまたはメソッドの情報

コンポーネントオブジェクトクラス情報

メモ:	インターフェース，ディスパッチインターフェース，コンポーネントオブジェクトクラス，列挙型，プロパティ，およびメソッドだけを追加または変更できます。構造体，共用体，型定義，およびモジュールもタイプライブラリにありますが，タイプライブラリエディタではそれらは表示のみで，編集することはできません。


参照
参照1036031

いつタイプライブラリを使うか

タイプライブラリのインポート

タイプライブラリの配布

有効な型

新しいタイプライブラリの作成

タイプライブラリへのインターフェースの追加

タイプライブラリへのプロパティとメソッドの追加

タイプライブラリへのコンポーネントオブジェクトクラスの追加

タイプライブラリへの列挙型の追加

タイプライブラリ情報の保存と登録


ツールバー
ツールバー1036032

タイプライブラリエディタの上部にあるツールバーには，クリックして各種の情報型の新しいインスタンスをタイプライブラリに作成するためのボタンがあります。

［Interface］	インターフェースの記述を追加します。

［DispInterface］	ディスパッチインターフェースの記述を追加します。

［CoClass］	コンポーネントオブジェクトクラスを追加します。

［Enum］	列挙型を追加します。

［Method］	インターフェースのメソッドを追加します。

［Property］	インターフェースのプロパティを追加します。

［更新］	Pascal タイプライブラリファイルをメモリに再生成します。

［登録］	現在のタイプライブラリを Windows レジストリに登録します。

ツールバーのボタンをクリックすると，その情報型のアイコンがタイプライブラリエディタの左側にあるオブジェクトリストペインに表示されます。ボタンをクリックするたびに，その情報型の追加インスタンスが現在のタイプライブラリに追加されます。オブジェクトリストペインでそのアイコンを選択して，右側のペインにその情報を表示したりそこで編集したりできます。選択した型に応じて，複数のページが右のペインに表示されることがあります。タイプライブラリエディタについての詳細は，タイプライブラリの操作を参照してください。


オブジェクトリストぺイン
オブジェクトリストペイン1036033

タイプライブラリエディタのオブジェクトリストペインにはライブラリ内にあるすべての要素とその型情報が一覧表示されます。これらの要素にはインターフェース，ディスパッチインターフェース，コンポーネントオブジェクトクラス，インターフェースのプロパティおよびメソッド，列挙型，構造体，共用体，型定義，モジュールがあります。オブジェクトリストペインは展開可能な階層ツリーで，そこには特定のインターフェースのメンバーがそのインターフェースに対する子として表示されます。

次の色分けされた記号がオブジェクトリストペイン (左側) のオブジェクトの左に表示されます。

アイコン	意味
	タイプライブラリ。これを展開すると，オブジェクトとインターフェースなどを含む個々の型情報を参照できる
	Interface
	DispInterface
	CoClass
	インターフェースのメソッド
	インターフェースのプロパティ
	列挙型
	構造体 (読み出し専用)
	共用体 (読み出し専用)
	型定義 (読み出し専用)
	モジュール (読み出し専用)


タイプライブラリ情報
タイプライブラリ情報1036034

オブジェクトリストペインでタイプライブラリを選択すると，その［属性］ページと［参照］ページが情報ペインに表示されます。表示したいページのタブをクリックします。

［Attributes］ページ

現在選択されているライブラリに関する型情報が表示されます。メインオブジェクトリストペインでタイプライブラリを選択すると次の属性とフラグが表示されます。

属性	意味

［名前］	タイプライブラリを説明する名前 (空白と句読点文字はなし)

［GUID］	インターフェースの 128 ビットのグローバルでユニークな識別子

［バージョン］	複数のバージョンのライブラリが存在する場合にライブラリの特定のバージョンを指す。バージョンはピリオドで区切られた 2 つの 10 進整数か 1 つの 10 進整数だけで示される。2 つ整数が並んでいるときの最初の整数はメジャーバージョン番号を表し，2 番目の整数はインターフェースのマイナーバージョン番号を表す。バージョン番号が 1 つの整数だけで示された場合，それはメジャーバージョン番号を表す。メジャーバージョン番号とマイナーバージョン番号は両方とも符号なし short 整数で 0～65535 の範囲にある

［LCID］	タイプライブラリのすべてのテキスト文字列と要素に対し使われる単一の特定言語を表すロケール識別子

［ヘルプファイル］	タイプライブラリと関連付けられているヘルプファイルの名前

［ヘルプ文字列］	ライブラリの短い説明。なるべくヘルプ文字列を提供するようにする

［ヘルプコンテキスト］	ライブラリのヘルプコンテキスト ID

次のフラグはほかのアプリケーションがサーバーを使う方法を指定します。

フラグ	意味

［None］	フラグなし

［Restricted］	ライブラリがマクロプログラマによって使われないようにする

［Control］	コンテナサイトが追加の TYPELIB やコンポーネントオブジェクトクラスを派生させる場合の派生元コントロールをライブラリが表すことを示す

［Hidden］	ライブラリは存在するがユーザー向けのブラウザでは表示すべきでないことを示す

［参照］ページ

現在選択されているライブラリが参照するほかのタイプライブラリが一覧表示されます。

列	意味

［タイプライブラリ］	別のタイプライブラリへの参照

［GUID］	参照されるタイプライブラリの 128 ビットのグローバルユニーク識別子


列挙型情報
列挙型情報1036035

オブジェクトリストペインで列挙型を選択すると，その［属性］ページと［メンバー］ページが情報ペインに表示されます。

［属性］ページ

メインオブジェクトリストペインで列挙型を選択すると次の属性が表示されます。

属性	意味

［名前］	列挙型の名前

［GUID］	インターフェースの 128 ビットのグローバルでユニークな識別子 (省略可能)

［ヘルプ文字列］	列挙型の短い説明。なるべくヘルプ文字列を提供するようにする

［ヘルプコンテキスト］	列挙型のヘルプコンテキスト ID

［バージョン］	複数のバージョンの列挙型が存在する場合に列挙型の特定のバージョンを指す。バージョンはピリオドで区切られた 2 つの 10 進整数か 1 つの 10 進整数だけで示される。2 つ整数が並んでいるときの最初の整数はメジャーバージョン番号を表し，2 番目の整数はインターフェースのマイナーバージョン番号を表す。バージョン番号が 1 つの整数だけで示された場合，それはメジャーバージョン番号を表す。メジャーバージョン番号とマイナーバージョン番号は両方とも符号なし short 整数で 0～65535 の範囲にある

［メンバー］ページ

列挙型の型定義が表示されます。さらに，各列挙型要素のヘルプ文字列とヘルプコンテキストが示されることもあります。

次に示すのはパネル上でのベベル用の列挙型のサンプルエントリで，各列挙型要素のヘルプ文字列を含んでいます。列挙型にはなるべくヘルプ文字列を提供するようにしてください。COM オブジェクトを使うアプリケーションはヘルプ文字列に依存することがあります。

bvNone = 0;

helpstring 'bvNone';

bvLowered = 1;

helpstring 'bvLowered';

bvRaised = 2;

helpstring 'bvRaised';


インターフェースとオブジェクトの情報
インターフェースとオブジェクトの情報1036036

インターフェースは ActiveX コンポーネントおよび OLE オートメーションなどの Communication Object Model (COM) コンポーネント間の通信を可能にする，意味的に関連したルーチンのグループのことです。

オブジェクトリストペインでインターフェースまたは COM オブジェクトを選択すると，その［属性］ページと［メンバー］ページが情報ペインに表示されます。

［属性］ページ

次の属性とフラグがインターフェースまたは COM オブジェクトについて表示されます。

属性	意味

［名前］	インターフェースまたはオブジェクトの名前

［GUID］	インターフェースまたはオブジェクトの 128 ビットのグローバルでユニークな識別子。この属性はインターフェースを区別する

［ヘルプ文字列］	インターフェースまたはオブジェクトの短い説明

［ヘルプコンテキスト］	ヘルプコンテキスト ID

［バージョン］	複数のバージョンのインターフェースまたはオブジェクトが存在する場合にその特定のバージョンを指す。バージョンはピリオドで区切られた 2 つの 10 進整数か 1 つの 10 進整数だけで示される。2 つ整数が並んでいるときの最初の整数はメジャーバージョン番号を表し，2 番目の整数はインターフェースのマイナーバージョン番号を表す。バージョン番号が 1 つの整数だけで示された場合，それはメジャーバージョン番号を表す。メジャーバージョン番号とマイナーバージョン番号は両方とも符号なし short 整数で 0～65535 の範囲にある

［親インターフェース］	このインターフェースの基本インターフェースの名前。インターフェースにのみ適用される

フラグ	意味

［DispInterface］	インターフェースは，仮想テーブルを通じてはアクセスできず IDispatch.Invoke を使ってアクセスしなければならないオブジェクトのメソッドとプロパティを記述する

［Hidden］	インターフェースは存在するがユーザー向けのブラウザでは表示すべきでないことを示す

［Non-extensible］	IDispatch 実装にはインターフェースの記述に示されたプロパティとメソッドのみが含まれることを示す

［Dual］	IDispatch を通じて，および仮想テーブルを通じて直接プロパティおよびメソッドをエクスポーズするインターフェースを示す

［Ole Automation］	インターフェースは OLE オートメーション互換型のみを使えることを示す。ディスパッチインターフェースは必然的に OLE オートメーション互換なので，このフラグはディスパッチインターフェースでは使えない

インターフェースの［メンバー］ページ

インターフェースのプロパティとメソッドを定義します。また，各メンバーに対し DispID を定義することもできます。次に示すサンプルはインターフェースに含まれるプロパティを定義しています。

property Caption: WideString; dispid 1;

property BevelInner: DAXPanelBevel; dispid 2;

property BevelOuter: DAXPanelBevel; dispid 3;

property BevelWidth: Integer; dispid 4;

property BorderWidth: Integer; dispid 5;

property WindowBorder: DAXBorderStyle; dispid 6;

property Font: Font; dispid 7;

次のサンプルはインターフェースに含まれるメソッドを定義しています。

procedure OnClick; dispid 1;

procedure OnEnter; dispid 2;

procedure OnExit; dispid 3;

procedure OnDblClick; dispid 4;

procedure OnKeyPress(var Key: Byte); dispid 5;

タイプライブラリ (.TLB) ファイルで使われるインターフェース定義言語（IDL: Interface Definition Language）では，レコード要素，パラメータ，関数戻り値をプロセス間で転送するのに必要な情報を記述するために ElemDescs が使われます。これらには IDL_FIN，IDL_FOUT，IDL_FRETVAL などのフラグが含まれます。

パラメータ型の前にポインタ型が付いている場合，タイプライブラリエディタは通常，その型を変数パラメータに変換します。タイプライブラリの保存時に，変数パラメータの対応する ElemDesc の IDL フラグがマークされます (IDL_FIN または IDL_FOUT)。

たいていの場合，型の前にポインタが付いていると ElemDesc IDL フラグはマークされません (IDL_FIN または IDL_FOUT)。またディスパッチインターフェースの場合，IDL フラグは一般に使われません。このような場合は，変数識別子の隣に {IDL_None} や {IDL_In} などのコメントがあるかもしれません。このようなコメントは，IDL フラグを正しくマークするためにタイプライブラリを保存するときに使われます。


コンポーネントオブジェクトクラス情報
コンポーネントオブジェクトクラス情報1036037

オブジェクトリストペインで OLE オブジェクトを選択すると，［メンバー］ページに次のような列が表示され，そのオブジェクトのメンバーが示されます。

列	意味

［Interface］	COM クラスが実装するインターフェースの名前

［GUID］	オブジェクトのメンバーインターフェースの GUID を示す

［Source］	メンバーがイベントのソースであることを示す

［Default］	Word Basic，Visual Basic，Delphi，Object PAL，Excel Basic などのマクロ言語用のデフォルトのプログラム可能インターフェースをインターフェースまたはディスパッチインターフェースが表すことを示す

［Restricted］	項目が Word Basic，Visual Basic，Delphi，Object PAL，Excel Basic などのマクロプログラマによって使われないようにする

新しいインターフェースを COM クラスに追加するには
このウィンドウで右クリックしたときに表示されるコンテキストメニューから選択します。コンテキストメニューには，このクラスに追加するために選択できるインターフェースのリストが表示されます。このリストには現在のタイプライブラリに定義されているインターフェースと，現在のタイプライブラリが参照するタイプライブラリに定義されているインターフェースが含まれます。


インターフェースのメンバー
インターフェースのプロパティとメソッド1036038

オブジェクトリストペインでインターフェースのプロパティまたはメソッドを選択すると，その［属性］ページが情報ペインに表示されます。

［属性］ページ

次の属性とフラグがインターフェースのプロパティまたはメソッドについて表示されます。

属性	意味

［宣言］	プロパティまたはメソッドの宣言

［ID］	ディスパッチ ID

［ヘルプ文字列］	プロパティまたはメソッドの説明の文字列を示す。項目を説明するタイトルであることが多い

［ヘルプコンテキスト］	プロパティまたはメソッドのヘルプコンテキスト ID を示す

［プロパティの種類］	プロパティが［読み書き可］，［読み出しのみ］，［書き込みのみ］，［参照のみ］のいずれであるかを示す

フラグ	意味

［By Reference］	値渡し以外に参照渡しでプロパティを渡す

［Restricted］	プロパティまたはメソッドがマクロプログラマによって使われないようにする

［Source］	イベントのソースであるオブジェクトまたは VARIANT をメンバーが返すことを示す

［Bindable］	プロパティがデータバインディングをサポートしていることを示す

［Request Edit］	プロパティが OnRequestEdit 通知をサポートしていることを示す

［Display Bindable］	ユーザーにバインディング可能として表示しなければならないプロパティを示す

［Default Bindable］	オブジェクトをもっともよく表す単一のバインディング可能プロパティを示す

［Hidden］	プロパティは存在するがユーザー向けのブラウザでは表示すべきでないことを示す

メモ:	OLE プロパティは［Write By Reference］を持つ場合があり，これは値渡しではなくポインタとしてプロパティを渡すことを意味します。Visual Basic などのアプリケーションでは，存在すれば［By Reference］を処理効率の最適化のために使います。値渡しではなく参照渡しだけでプロパティを渡すには，プロパティ型として［参照のみ］を使います。値渡しだけでなく参照渡しでもプロパティを渡すには，［By Reference］フラグをクリックします。


エラーログペイン
エラーログペイン1036039

タイプライブラリエディタにタイプライブラリをロードする場合，OLE 型が Pascal 型に直接はマップしないため，変換エラーが発生する可能性があります。タイプライブラリのロード時または保存時に，構文エラーと変換エラーはエラーログペインに一覧表示されます。

たとえば，整数へのポインタへのポインタは整数への変数ポインタにマップしますが，Pascal ではすべてのパラメータが名前付きの型でなければならないので，これは不当な型です。したがって，これは変数ポインタに変換されます。これは完全な一致ではないため，元の型に関する情報はタイプライブラリの保存時に失われます。エラーログにはこのような問題が示されるので，警告に注意したり問題を訂正したりできます。


タイプライブラリについて
タイプライブラリについて1036040

Communication Object Model はタイプライブラリを使って COM サーバー上で利用可能なオブジェクトとインターフェースの型を識別します。

型情報を取得するには

オブジェクトの型情報をそのオブジェクトの実行中インスタンスに問い合せる

または，タイプライブラリをロードして読み込む

タイプライブラリは ActiveX コントロールまたは ActiveX サーバーによってエクスポーズされたデータ型，インターフェース，メンバー関数，およびオブジェクトクラスについての情報が入っているファイルです。タイプライブラリをアプリケーションまたは OCX に入れると，その中に入っているオブジェクトに関する情報をほかのアプリケーションやプログラミングツールが利用できるようになります。

タイプライブラリには次のものが入っています。

データ型に関する情報

インターフェースまたはコンポーネントオブジェクトクラスなどの 1 つ以上のオブジェクトの記述。これらの各記述は通常「型情報」と呼ばれる

ほかのタイプライブラリからの型記述への参照

タイプライブラリファイルには COM サーバーの型情報が格納されています。格納形態は，ユニット，ヘッダーファイル，DEF ファイル，またはインポートライブラリにアプリケーション，DLL，または Windows EXE に関する必要な情報が格納される場合と似ています。実際には，これらのファイルに格納していた情報の大部分はタイプライブラリに格納できます。

タイプライブラリに関する情報についての詳細は，次のトピックを参照してください。

いつタイプライブラリを使うか

タイプライブラリの配布

有効な型

新しいタイプライブラリの作成

タイプライブラリへのインターフェースの追加

タイプライブラリへのプロパティとメソッドの追加

タイプライブラリへのコンポーネントオブジェクトクラスの追加

タイプライブラリへの列挙型の追加

タイプライブラリ情報の保存と登録


いつタイプライブラリを使うか
いつタイプライブラリを使うか1036041

Delphi ウィザードを使って Delphi コンポーネントを ActiveX コントロールに変換する場合，タイプライブラリは自動生成されるので作成する必要がありません。通常，タイプライブラリエディタを使ってタイプライブラリを作成する必要があるのは，カスタム機能を COM オブジェクトに追加してこの機能をクライアントにエクスポーズしたい場合だけです。

ウィザードを使えば，Delphi コンポーネントを ActiveX コントロールとして作成できます。その後で，自動生成されたタイプライブラリは Delphi コンポーネントの組み込み機能をサポートするだけです。クライアントに提供したい追加のメソッド，イベント，プロパティについては，そのオブジェクトのタイプライブラリファイルに追加しなければなりません。

内部で使うためだけにインターフェースを定義する場合，アプリケーション内ではタイプライブラリを作成する必要はありません。インターフェース定義を Object Pascal で直接記述してユニットを追加することができます。『Object Pascal Language Guide』の第 12 章に，Delphi でインターフェースを宣言するための構文の説明があります。

タイプライブラリは通常，定義されたオブジェクトの各セットに使ってください。タイプライブラリが有用であったり必須であるのは次の場合です。

コンパイル時に仮想テーブル参照がバインディングされるので，仮想テーブルバインディングをサポートしているエクスポーズされたオブジェクトはタイプライブラリで記述しなければならない

Delphi TTypedComObject クラスのすべての下位オブジェクトなど，IProvideClassInfo インターフェースをサポートするクラスからインスタンス化したオブジェクトはタイプライブラリを持っていなければならない

ActiveX コントロールはタイプライブラリを必要とするが，それは ActiveX コントロールを含む DLL にリソースとして含まれていなければならない

型チェックとアーリーバインディングのために OLE オートメーションを使うアプリケーション用にタイプライブラリは有効

ドラッグアンドドロップで使用されるオブジェクトを識別する必要がある場合（そうでなければ通常はタイプライブラリを使わない），タイプライブラリは有効


タイプライブラリの配布
タイプライブラリの配布1036042

ActiveX コントロールウィザードを使って ActiveX コントロールを作成する場合，コントロールの構築時にタイプライブラリはリソースとして OCX に自動的にコンパイルされます。

タイプライブラリは次の形態で配布できます。

.OCX ファイル中のリソース。このリソースには TYPELIB 型と整数の ID が必要である。これはリソース (.RC) ファイル内で次のように宣言しなければならない

1 typelib mylib1.tlb

2 typelib mylib2.tlb

OCX には複数のタイプライブラリリソースを入れることができる。アプリケーション開発者はリソースコンパイラを使って .TLB ファイルを自分の OCX へ追加する。1 つまたは複数のタイプライブラリリソースを備えた OCX の拡張子は一般に .OLB (オブジェクトライブラリ) となる

.EXE ファイル中のリソース。このファイルには複数のタイプライブラリを入れることができる

スタンドアロンのバイナリファイル。タイプライブラリエディタから出力された .TLB ファイルはバイナリファイルである


有効な型
有効な型1036043

次の型がタイプライブラリで有効です。OLE オートメーション互換の列は，［OLE Automation］フラグまたは［DispInterface］フラグにチェックマークが付いているインターフェースがその型を使えるかどうかを指定します。

OLE

OLE 	オートメーション

Pascal 型	バリアント型	互換性	説明

Smallint	VT_I2	あり	符号付き 2 バイト整数

Integer	VT_I4	あり	符号付き 4 バイト整数

Single	VT_R4	あり	4 バイト実数

Double	VT_R8	あり	8 バイト実数

Currency	VT_CY	あり	通貨

TDateTime	VT_DATE	あり	日付

WideString	VT_BSTR	あり	バイナリ文字列

IDispatch	VT_DISPATCH	あり	IDispatch インターフェースへのポインタ

SCODE	VT_ERROR	あり	Ole エラーコード

WordBool	VT_BOOL	あり	True = -1，False = 0

OleVariant	VT_VARIANT	あり	Ole バリアント

IUnknown	VT_UNKNOWN	あり	IUnknown インターフェースへのポインタ

Shortint	VT_I1	なし	符号付き 1 バイト整数

Byte	VT_UI1	あり	符号なし 1 バイト整数

Word	VT_UI2	なし*	符号なし 2 バイト整数

UINT	VT_UI4	なし* 	符号なし 4 バイト整数

Comp	VT_I8	なし	符号付き 8 バイト実数

Largeuint	VT_UI8	なし	符号なし 8 バイト実数

SYSINT	VT_INT	なし* 	システムに依存した整数 (Win32 = Integer)

SYSUINT	VT_UINT	なし* 	システムに依存した符号なし整数

HResult	VT_HRESULT	なし	32 ビットエラーコード

Pointer	VT_PTR -> VT_VOID	なし	型なしポインタはない

TSafeArray	VT_SAFEARRAY	なし	OLE 保障配列

PChar	VT_LPSTR	なし	Char へのポインタ

PWideChar	VT_LPWSTR	なし	WideChar へのポインタ

メモ:	Word，UINT，SYSINT，SYSUINT は一部のアプリケーションとは OLE オートメーション互換です。

上記の Pascal 型以外に，ライブラリに定義されているインターフェースおよび型と，参照されているライブラリに定義されているインターフェースおよび型はタイプライブラリ定義の中で使えます。


TSafeArray
TSafeArray1036044

タイプライブラリエディタでは，TSafeArray はそのコンポーネント型を指定しなければなりません。

たとえば，次のコードでは，TSafeArray はコンポーネント型の Integer を指定しています。

procedure HighLightLines(Lines: TSafeArray(Integer));

TSafeArray のコンポーネント型は OLE オートメーション互換の型でなければなりません。Delphi のタイプライブラリ変換ユニットでは，コンポーネント型は不要です。


新しいタイプライブラリの作成
新しいタイプライブラリの作成1036045

タイプライブラリを作成する標準的な方法は，Interface Description Language (IDL) または Object Language (ODL) でスクリプトを記述することです。しかし，Delphi のタイプライブラリエディタではこの作業が不要で，ActiveX コントロール，ActiveX サーバー，およびその他の COM オブジェクトのタイプライブラリ作成が簡単にできます。

新しいタイプライブラリを作成するには

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択します。

3.	［タイプライブラリ］アイコンを選択します。

4.	［OK］をクリックします。

タイプライブラリエディタが開き，タイプライブラリの名前を入力するよう求められます。

5.	タイプライブラリの名前を入力して〔Enter〕を押します。

これでタイプライブラリへインターフェース，コンポーネントオブジェクトクラス，列挙型，プロパティ，メソッドを追加できます。


タイプライブラリへのインターフェースの追加
タイプライブラリへのインターフェースの追加1036046

インターフェースを追加するには

1.	ツールバーでインターフェースのアイコンをクリックします。

インターフェースがオブジェクトリストペインに追加され，名前を追加するよう求められます。

2.	インターフェースの名前を入力して〔Enter〕を押します。

新しいインターフェースには，必要に応じて変更できるデフォルト設定と属性が入っています。［メンバー］ページは空で，インターフェースの目的に応じてプロパティやメソッドを追加できます。


タイプライブラリへのプロパティとメソッドの追加
タイプライブラリへのプロパティとメソッドの追加1036047

インターフェースへインターフェースメンバーを追加するには

1.	追加するインターフェースメンバーを選択します。

2.	ツールバーでプロパティかメソッドのアイコンをクリックします。

インターフェースメンバーがオブジェクトリストペインに追加され，名前を追加するよう求められます。

3.	メンバーの名前を入力して〔Enter〕を押します。

新しいメンバーの［属性］ページにはデフォルトの属性が入っています。これらの属性はメンバーに合わせて変更できます。

また，［メンバー］ページに直接入力することによってプロパティやメソッドを追加することもできます。たとえば，次のプロパティ宣言をインターフェースの［メンバー］ページに入力できます。

property AutoSelect: WordBool; dispid 1;

property AutoSize: WordBool; dispid 2;

property BorderStyle: BorderStyle; dispid 3;

メンバーをインターフェースの［メンバー］ページに追加した後では，そのメンバーはオブジェクトリストペインで個別の項目として表示されます。それぞれが独自の［属性］ページを持っており，そこで新しいメンバーの各属性を変更できます。


タイプライブラリへのコンポーネントオブジェクトクラスの追加
タイプライブラリへのコンポーネントオブジェクトクラスの追加1036048

タイプライブラリへコンポーネントオブジェクトクラスを追加するには

1.	ツールバーでコンポーネントオブジェクトクラスのアイコンをクリックします。

コンポーネントオブジェクトクラスがオブジェクトリストペインに追加され，名前を追加するよう求められます。

2.	クラスの名前を入力して〔Enter〕を押します。

新しいクラスの［属性］ページにはデフォルトの属性が入っています。これらの属性はクラスに合わせて変更できます。［メンバー］ページは空です。

メンバーを追加するには

1.	クラスの［メンバー］ページで右クリックします。

選択できるインターフェースのリストがコンテキストメニューに表示されます。このリストには現在のタイプライブラリに定義されているインターフェースと，現在のタイプライブラリが参照するタイプライブラリに定義されているインターフェースが含まれます。

2.	クラスに実装させたいインターフェースをダブルクリックします。

インターフェースがその GUID などの属性と一緒にページに追加されます。


タイプライブラリへの列挙型の追加
タイプライブラリへの列挙型の追加1036049

タイプライブラリへ列挙型を追加するには

1.	ツールバーで列挙型のアイコンをクリックします。

列挙型がオブジェクトリストペインに追加され，名前を追加するよう求められます。

2.	メンバーの名前を入力して〔Enter〕を押します。

新しい列挙型は空で，その［属性］ページにはデフォルトの属性が入っています。これらの属性は列挙型に合わせて変更できます。列挙型の［メンバー］ページは空です。

［メンバー］ページに直接入力することによって列挙型に値を追加します。たとえば，次の宣言を，ボタンコントロールが使う列挙型の［メンバー］ページに入力できます。

mbLeft = 0;

helpstring 'mbLeft';

mbRight = 1;

helpstring 'mbRight';

mbMiddle = 2;

helpstring 'mbMiddle';


タイプライブラリ情報の保存と登録
タイプライブラリ情報の保存と登録1036050

タイプライブラリ情報は OLE 複合ドキュメントファイルである .TLB ファイルに格納されています。

Delphi はタイプライブラリ情報を Pascal ファイルにも格納します。.PAS ファイルはタイプライブラリのインターフェース，型，クラスの情報を含むユニットです。このファイルは編集しないでください。行った変更は，次回のタイプライブラリの保存時にオーバーライドされます。

Delphi ウィザードを使って ActiveX コントロール，オートメーションオブジェクト，または ActiveForm を作成すると，タイプライブラリは実装ユニットと一緒に自動生成されます。実装ユニットはタイプライブラリの保存時または更新時に自動更新されます。

タイプライブラリ情報はタイプライブラリエディタから格納することができます。

保存

更新

登録


タイプライブラリの保存
タイプライブラリの保存1036051

タイプライブラリを保存するには［ファイル(F)｜上書き保存(S)］を選択します。

タイプライブラリの保存では以下に示すことが行われます。

構文検査の実行

.TLB ファイルへの情報の保存

PAS ファイルへの情報の保存

タイプライブラリが ActiveForm，ActiveX コントロール，またはオートメーションオブジェクトと関連付けられている場合，モジュールマネージャに実装を更新するよう通知する


タイプライブラリの更新
タイプライブラリの更新1036052

タイプライブラリを更新するにはツールバーの［更新］アイコンを選択します。

タイプライブラリの更新では次のことが行われます。

構文検査の実行

メモリだけに Pascal タイプライブラリファイルを再生成する。ディスクへは保存しない

タイプライブラリが ActiveForm，ActiveX コントロール，またはオートメーションオブジェクトと関連付けられている場合，モジュールマネージャに実装を更新するよう通知する

メモ:	タイプライブラリから項目を削除したかその名前を変更してあれば，実装を更新すると重複したエントリが作成される可能性があります。その場合は，コードを正しいエントリへ移動して重複したエントリを削除しなければなりません。


タイプライブラリの登録
タイプライブラリの登録1036053

タイプライブラリを登録するにはツールバーの［登録］ボタンをクリックします。

タイプライブラリの登録では次のことが行われます。

構文検査の実行

タイプライブラリの Windows レジストリへのエントリの追加


Using DDE
Using DDE1039001

See also

Dynamic Data Exchange (DDE) sends data to and receives data from other applications. With Delphi, you can use this data to exchange text with other applications. You can also send commands and macros to other applications, so your application can control other applications.

Here is a typical way to use DDE: a link between two applications is established, either by your application or the other application. Once this link (called a conversation) is established, the two applications can continuously and automatically send text data back and forth. When the text changes in one application, DDE automatically updates the text in the other.

To understand DDE applications, you need to become familiar with the concept of DDE conversations.

When to use DDE

You want to use DDE when exchanging distinct text strings. If all you want to know is the bottom line of a profits spreadsheet, it makes sense to link the cell that contains the bottom line to a Delphi DDE client application.

You could then output the data in an edit box or label. DDE protects the data in the spreadsheet by not allowing the user to activate and edit the spreadsheet from your client application.

Note:	Not all applications support DDE. To determine whether an application supports DDE, refer to its documentation.


See also1039002

Creating DDE client applications

Creating DDE server applications


DDE conversations
DDE conversations1039003

See also

DDE conversations consist of a DDE client application and a DDE server application. With Delphi, you can create both DDE clients and DDE servers. In fact, a single Delphi application can be both a DDE client and a DDE server at the same time.

A DDE conversation is defined by the following three characteristics:

DDE services

DDE topics

DDE items

Note:	See the documentation for the DDE server for specific information about specifying the services, topics, or items of a conversation.

DDE services

The service of a conversation is usually the name of the DDE server application's main executable file without the .EXE extension.

Sometimes the service name can differ from the main executable file name.

When the server is a Delphi application, the service is the project name without the .DPR or .EXE extension.

Note:	Sometimes DDE services are called application names. The terminology is interchangeable.

DDE topics

The topic of a DDE conversation is a unit of data, identifiable to the server, containing the linked text. Typically, the topic is a file.

When the server is a Delphi application, the topic is either the Caption of the form containing the data you want to link (if a TDDEServerConv component has not been used) or the Name of the DDE server conversation component (if a TDDEServerConv component has been used).

DDE items

The item of a DDE conversation identifies the actual piece of data to link, for example, spreadsheet cells or database fields.

The syntax used for specifying the DDE item depends on the DDE server application.

When the server is a Delphi application, the item is the Name of the linked TDDEServerItem component.


See also1039004

Creating DDE client applications

Creating DDE server applications

Using DDE


Creating DDE client applications
Creating DDE client applications1039005

See also	Example

You can create a DDE client by adding a DDE client conversation (TDDEClientConv) component and a DDE client item (TDDEClientItem) component to a form.

Client applications can poke data (send data to the server) with the PokeData or PokeDataLines method.

Clients can control the server by running it or sending macros with the ExecuteMacro or ExecuteMacroLines method.

To create a DDE client,

1.	Add a DDE client conversation component (TDDEClientConv) and a DDE client item component (TDDEClientItem) to a form.

2.	Assign the name of the conversation component to the DDEConv property of the client item component.

To establish a link at design time, choose this value from a list of possible conversations for DDEConv in the Object Inspector.

To establish a link at run time, your application must execute code that assigns the value to the DDEConv property.


Example1039006

The following example links an item component named DDEClientItem1 to a conversation component named DDEClientConv1:

DDEClientItem1.DDEConv := 'DDEClientConv1';


See also1039007

Controlling other applications with DDE

Creating DDE server applications

Establishing a link with a DDE server

Poking data

Using DDE


Establishing a link with a DDE server
Establishing a link with a DDE server1039008

If you have access to the DDE server application and data, you can establish a DDE link by pasting it from the Clipboard at design time.

To establish a DDE link at design time,

1.	Activate the server application and select the data to link to your client application.

2.	Copy the data and DDE link information to the Clipboard from the server application by choosing Copy from the Edit menu of the server.

3.	Activate Delphi and select the DDE client conversation component.

4.	Click the ellipsis button for either the DDEService or the DDETopic property in the Object Inspector.

The DDE Info dialog box appears.

5.	Choose Paste Link.

The service and topic fill in with the correct values automatically. If the Paste Link button is disabled, then the application you intended to be the server does not support DDE, or the DDE information was not successfully copied to the Clipboard.

6.	Choose OK.

The DDEService and DDETopic properties now contain the appropriate values to establish a DDE link.

7.	Select the DDE client item component and choose the name of the linked DDE client conversation component for the DDEConv property from the list in the Object Inspector.

8.	If the Clipboard still contains the DDE link information, choose the appropriate value for the DDEItem property from the list in Object Inspector. Otherwise, type the correct value for the DDEItem property.

To establish a DDE link at run time,

1.	Specify the DDE service and topic with the SetLink method of the DDE client conversation component.

The following example establishes a link to a Borland Paradox 5.0 table named GADGETS.DB in the working directory:

DDEClientConv1.SetLink('PDOXWIN', ':WORK:GADGETS.DB');

2.	Assign the item to the DDEItem property of the DDE client item component.

The following example establishes a link to the Price field of the Paradox table:

DDEClientItem1.DDEItem := 'PRICE';


Processing DDE linked data
Processing DDE linked data1039009

Example

Before you can process data from a DDE server, you first need to establish a DDE link.

After establishing a DDE link, the linked data appears in the Text property of the DDE client item component. (If the data is too long to be stored in a string, it is stored in the Lines property. The data is continuously updated by the DDE server, and an OnChange event of the client item component occurs whenever the data changes.

To process linked text data,

1.	Add an edit box (Tedit component) to your form.

2.	Write a statement that assigns the value of the Text property to the Text property of the edit box.

Attach the assignment statement to the OnChange event handler of the DDE client item.


Example1039010

The following event handler assigns the text of the DDE client item to an edit box.

procedure TForm1.DDEClientItem1.Change(sender: TObject);

begin

  Edit1.Text := DDEClientItem1.Text;

end;


Poking data
Poking data1039011

Example

Poking data means sending data from your DDE client application to the DDE server application, which is opposite the usual data flow direction for DDE.

To poke data, call the PokeData method of a DDE client conversation component. To poke text data that is too long to be contained in a string, use PokeDataLines.

PokeData has two parameters:

The first parameter specifies the item of the DDE conversation (specified in the DDEItem property of the associated DDE client item component).

The second parameter is a string containing the text to send.


Example1039012

The following example sends the text 'Hello' from a DDE client conversation component named DDEClientConv1 to a linked DDE server. The string is inserted into the DDE item specified in the DDEItem property of the DDE client item component named DDEClientItem1:

DDEClientConv1.PokeData(DDEClientItem1.DDEItem, 'Hello');


Controlling other applications using DDE
Controlling other applications using DDE1039013

Example

All DDE client applications can control DDE server applications. When your DDE client tries to establish a link with a DDE server that is not running, the client activates the server and loads the conversation topic (specified in the DDETopic property).

The ConnectMode property of a DDE client conversation component has two possible values:

Value	When active

ddeAutomatic	Your client will run the server upon run-time creation of the form containing the DDE client conversation component.

ddeManual	Your application must execute the OpenLink method of the DDE client conversation component.

Using macros

Another way to control other applications is to execute macro commands. Use the ExecuteMacro method of the DDE client conversation component to send a string containing one or more macro commands to the server. The server then processes the macro. To send a list of macro strings to the DDE server, use ExecuteMacroLines

Note:	Not all DDE servers can process macros. See the documentation for the server application to determine whether it supports macros and for its macro syntax.


Example1039014

The following example uses macros to tell Microsoft Excel 4.0 to close its active worksheet by executing the following code in your client application, assuming your DDE client conversation component is named DDEClientConv1:

DDEClientConv1.ExecuteMacro('[FILE.CLOSE()]', False);


Creating DDE server applications
Creating DDE server applications1039015

Example

DDE server applications respond to DDE client. Typically, they contain data that the client application needs to access. Servers simply update clients.

If you want to handle macros sent by the DDE client, use both a TDDEServerItem and a TDDEServerConv to create the DDE server. Then, you can use the OnExecuteMacro event of the DDE server conversation component to process the macro. Also, use both components if you want the Name of the DDE server conversation component to be the topic of the DDE conversation. With only a DDE server item component, the topic of the conversation is the Caption of the form containing the DDE server item.

To create a DDE server using only a DDE server item component,

Add a DDE server item (TDDEServerItem) component to a form.

To create a DDE server using a DDE server conversation component,

1.	Add a DDE server conversation (TDDEServerConv) component and a DDE server item component to a form.

2.	Assign the name of the conversation component to the ServerConv property of the item component.

To establish a link at design time, choose this value from a list of possible conversations for ServerConv in the Object Inspector.

To establish a link at run time, your application must execute code that assigns the value to the ServerConv property.


Example1039016

The following example links an item component named DDEServerItem1 to a conversation component named DDEServerConv1:

DDEServerItem1.ServerConv := 'DDEServerConv1';


Establishing a link with a DDE client
Establishing a link with a DDE client1039017

Example

Linking a DDE server to a DDE client enables your client application to share data with the client application.

To establish a DDE link,

1.	Use the CopyToClipboard method of the DDE server item component to copy the value of the Text property (or Lines property), along with DDE link information, to the Clipboard.

2.	Insert the linked data into the DDE client application. Typically, do this by choosing the appropriate command (such as Edit|Paste Special or Edit|Paste Link) of the client application.

Note:	The method for establishing a DDE link depends on the DDE client application. See the documentation for the client for specific information about establishing DDE links. If the DDE client is another Delphi application, see Establishing a link with a DDE server.


Example1039018

The following example creates a link from a DDE server item component named DDEServerItem1 to a WordPerfect 6.0 document. If you do not have WordPerfect, this example is worth examining because the steps required are probably similar for any other DDE client application that can paste links.

1.	At run time, your DDE server application should execute the following code:

DDEServerItem1.CopyToClipboard;

2.	Activate WordPerfect and choose Edit | Paste Special.

The WordPerfect Paste Special dialog box appears.

3.	Choose Paste Link.

The Paste Special dialog box closes, and the linked text from the Value property of DDEServerItem1 will appear at the insertion point in the WordPerfect document. When the Value property changes, the text in the WordPerfect document will be updated automatically.


Using the printer object
Using the Printer object1040001

See also	Example	TPrinter reference

The Printer object provides several methods and properties that enable you to control the printing of documents from your application. These methods and properties interact with the Print and Printer Setup common dialog boxes.

Canvas

The canvas represents the surface of the currently printing document. You assign the contents of your text file to the Canvas property of the printer object by using AssignPrn. The printer object then directs the contents of the Canvas property (your text file) to the printer.

Fonts

Represents the list of fonts supported by the current printer. These fonts appear in the Font list of the Font dialog box.

Any font selected from this dialog box is reflected back into the Font property for the memo component that contains the text you want to print. However, the printer object has no such relationship to the Font dialog box or to the Font property for the memo. Unless your program specifies otherwise, the printer uses the default (System) font that is returned by the Windows device driver to print your text file.

To change the printer's font,

Assign the Font property for the memo component (or other component whose text you want to print) to the Font property for the printer object's Canvas. This downloads the selected font to the printer.


See also1040002

Printing the contents of a memo


Printing the contents of a memo
Printing the contents of a memo1040003

See also	Example

To print the contents of a memo component,

1.	Assign a text-file variable to the printer by calling AssignPrn.

2.	Create and open the output file by calling Rewrite.

Any Write or Writeln statements sent to the file variable are then written on the Canvas of the printer object.

The AssignPrn procedure is declared in the Delphi Printers unit, so you must add Printers to the uses clause of the unit that calls AssignPrn.

When the printer is ready for input, you can write the contents (Lines property) of the memo to the printer.


See also1040004

Using the printer object


Example1040005

The following example prints the contents of a Memo field when the user chooses File|Print.

procedure TForm1.Print1Click(Sender: TObject);

var

  Line: Integer;

  PrintText: TextFile;   {declares a file variable}

begin

  if PrintDialog1.Execute then

  begin

    AssignPrn(PrintText);   {assigns PrintText to the printer}

    Rewrite(PrintText);     {creates and opens the output file}

    Printer.Canvas.Font := Memo1.Font;  {assigns Font settings to the canvas}

    for Line := 0 to Memo1.Lines.Count - 1 do

      Writeln(PrintText, Memo1.Lines[Line]);	{writes the contents of the Memo1 to the printer object}

    CloseFile(PrintText); {Closes the printer variable}

  end;

end;


Accessing and editing menus at run time
Accessing and editing menus at run time1041001

See also

While you use the Delphi Menu Designer to visually design your application menus, the underlying code is what makes the menus ultimately useful. Each menu command needs to be able to respond to an OnClick event, and there are many times when you want to change menus dynamically in response to program conditions.

You can design your own application menus, or use the predesigned menu templates included with Delphi. For information about how to design menu bars and pop-up (local) menus, see Designing Menus.

The following topics describe how to associate code with menu events at design time, and how to access and modify menus in your running application.

Associating menu events with code

Manipulating menu items at runtime

Merging menus

Disabling menu items

Opening a dialog box with a menu command


See also1041002

TPopupMenu component

Providing a list of open documents in a menu


Opening a dialog box with a menu command
Opening a dialog box with a menu command1041003

See also

To open a dialog box with a menu command, you can call the Execute method of the dialog box in response to the menu item's OnClick event. For example, the following event-handler code calls the Open File common dialog box when the user selects the application's File|Open command, (assuming the command's Name property has been set to FileOpen).

procedure TForm1.FileOpenClick(Sender: TObject);

begin

  OpenFileDialog1.Execute;

end;

Of course, you still need to specify how you want your application to interact with the dialog box once it is open.


See also1041004

Accessing and editing menus at run time

Associating menu events with code

Manipulating menu items at runtime

Manipulating open child windows


String List editor
String List editor1042001

See also

Use the String List editor at design time to add, edit, load, and save strings into any property that has been declared as TStrings.

A string-list property appears in the Object Inspector with (TStrings) in the value column. When you double-click {TStrings}, the String List editor appears.

The String List Speed Menu contains the following commands:

Load

Click Load to display the Load String List dialog box, where you can select an existing file to read into the String List editor.

Save

Click Save to write the current string list to a file. Delphi opens the Save String List dialog box, where you can specify a directory and file name.


See also1042002

Working with string lists


Load String List dialog box
Load � (String List Speed Menu)1042003

Use the Load string list dialog box to specify a predefined string list that has been saved as a text file to load into a property.

Dialog box options

File Name

Enter the name of the file you want to load or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose a filter to display the different types of files. By default the text files (*.TXT) for the current directory are displayed in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


Save String List dialog box
Save � (String List Speed Menu)1042004

Use the Save string list dialog box to store the string list from the String List editor into a text file.

Dialog box options

File Name

Enter the name of the file you want to save or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose a filter to display the different types of files. By default the text files (*.TXT) for the current directory are displayed in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


Picture editor
Picture editor1042005

Use the Picture editor to select an image to add to any of the graphic-compatible components and to specify an icon for your form.

The Glyph property appears in the Object Inspector when you select a graphic compatible component. Click the ellipse (�) in the value box to display the Picture editor.

Note: To open the Picture editor from an Image component, you can also double-click the component in the form.

The Picture Editor provides the following commands.

Load

Display the Load Picture dialog box, where you can select an existing file to read into the Picture editor. For more information about loading images into the Picture editor, see Loading an image at design time.

Save

Display the Save Picture As dialog box, where you can specify a directory and file name in which to store the image.

Clear

Remove the association between the current image and the selected component.


Load Picture dialog box
Load Picture dialog box1042006

See also

Use the Load Picture dialog box to select an image to add to any of the graphic-compatible components and to specify an icon for your form.

To open the Load Picture dialog box,

In the Picture editor, click Load.

Dialog box options

File Name

Enter the name of the file you want to load or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose a filter to display the different types of image files. By default the icon files (*.ICO) for the current directory are displayed in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


See also1042007

Loading an image at design time


Save Picture As dialog box
Save Picture As dialog box1042008

Use the Save Picture As dialog box to store the image loaded in the Picture editor into a new file or directory.

To open the Save Picture As dialog box,

In the Picture editor, click Save As.

Dialog box options

File Name

Enter the name of the file you want to load or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose filter to display the different types of image files. By default the icon files (*.ICO) for the current directory are displayed in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


Notebook editor
Notebook editor1042009

Use the Notebook editor to add, edit, remove, or rearrange pages in either a TabbedNotebook component or Notebook component. You can also use the Notebook editor to add or edit Help context numbers for each notebook page.

The Notebook editor displays the current pages of the notebook in their current order, and it also displays the Help context associated with that page.

To open the Notebook editor,

1.	Place a Notebook component or TabbedNotebook component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for the Pages property.

Double-click the Value column for the Pages property.

Edit

Click Edit to open the Edit Page dialog box, where you can modify the page name and Help context number for the selected notebook page.

Add

Click Add to open the Add Page dialog box, where you can create a new notebook page.

Delete

Click Delete to remove the selected page from the notebook.

Move Up/Move Down

Click Move Up or Move Down to rearrange the order of the selected page or pages.


Edit Page dialog box
Edit Page dialog box1042010

See also

Use the Edit Page dialog box to edit existing notebook pages from either the Notebook component or the TabbedNotebook component.

To open this dialog box,

In the Notebook editor, click Edit.

Dialog box options

Page Name

Enter the name of the notebook page. There is a 255-character limit on page names.

Help Context

Enter the context ID number for the notebook page. This number is significant if you want to have context-sensitive help for the individual pages of the notebook. The Help context is optional.


See also1042011

Page controls

Notebook editor

Windows 3.1 components


Add Page dialog box
Add Page dialog box1042012

See also

Use the Add Page dialog box to add notebook pages to either the Notebook component or the TabbedNotebook component.

To open this dialog box,

In the Notebook editor, click Add.

Dialog box options

Page Name

Enter the name of the notebook page. There is a 255-character limit on page names.

Help Context

Enter the context ID number for the notebook page. This number is significant if you want to have context-sensitive Help for the individual pages of the notebook. The Help context is optional.


See also1042013

Page controls

Notebook editor

Windows 3.1 components


Input Mask editor
Input Mask editor1042014

See also

Use the Input Mask editor to define an edit box that limits the user to a specific format and accepts only valid characters. For example, in a data entry field for telephone numbers you might define an edit box that accepts only numeric input. If a user then tries to enter a letter in this edit box, your application will not accept it.

Use the Input Mask editor to edit the EditMask property of the MaskEdit component.

To open the Input Mask editor,

1.	Place a MaskEdit component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for the EditMask property.

Double-click the Value column for the EditMask property.

Input Mask

Define your own masks for the edit box. You can use special character to specify the mask; for a listing of those characters, see the EditMask property.

The mask consists of three fields separated by semicolons. The three fields are

The mask itself; you can use predefined masks or create your own.

The character that determines whether or not the literal characters of the mask are saved as part of the data.

The character used to represent a blank in the mask.

Save Literal Characters

Check to store the literal characters from the edit mask as part of the data. This option affects only the Text property of the MaskEdit component. If you save data using the EditText property, literal characters are always saved.

This check box toggles the second field in your edit mask.

Character For Blanks

Specify a character to use as a blank in the mask. Blanks in a mask are areas that require user input.

This edit box changes the third field of your edit mask.

Test Input

Use Test Input to verify your mask. This edit box displays the edit mask as it will appear on the form.

Sample Masks

Select a predefined mask to use in the MaskEdit component. When you select a mask from this list, Delphi places the predefined mask in the Input Mask edit box and displays a sample in the Test Input edit box. To display masks appropriate to your country, choose the Masks button.

Masks

Choose Masks to display the Open Mask File dialog box, where you choose a file containing the sample masks shown in the Sample Masks list box.


See also1042015

TMaskEdit component


Masked Text editor
Masked Text editor1042016

See also

Use the Mask Test editor to enter Values into the edit mask.

Use the Masked Text editor to edit the Text property of the MaskEdit component.

To open the Masked Text editor,

1.	Place an MaskEdit component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for the Text property.

Double-click the Value column for the Text property.

Input Text edit box

Enter initial values for the MaskEdit component. You can overwrite these values at run time.

Edit Mask label

Displays the mask definition for the current component.


See also1042017

EditText property

TMaskEdit component

About Input Mask editor


Font editor
Font editor1042018

See also

Use the Font editor to specify, at design time, a font and other font attributes for the selected component or form. Changes you make using the Font editor are reflected in the Font property for a component.

To open the Font editor,

1.	Select any component or the form.

2.	Do one of the following:

Click the ellipsis button in the Value column for the Font property or one of the other properties listed below that use the Font editor.

Double-click the Value column for the Font property or one of the other properties listed below that use the Font editor.

Font

Select a font from the list of all the available fonts you can use in your application.

Font Style

Select a style for the font. This combo box displays only those styles that are available for the selected font. For most of the available fonts there are four possible styles:

Regular

Italic

Bold

Bold Italic

Size

Select a size for the font. This combo box displays only those font sizes that are available for the selected font.

Effects

Check these options to make the text strikethrough or underlined.

Color

Select a color for the font. This combo box lists all the available colors for the selected font.

Sample area

Displays a sample of the selected font before you apply it to the components. The font within this area is updated with every change you make to the font settings.

Script

Lists the available language scripts for the selected font.


See also1042019

TFontDialog component


Color editor
Color editor1042020

Use the Color editor to specify or define a color for the selected component. Changes you make using the Color editor are reflected in the Color property for a component.

To open the Color editor,

1.	Select any component or the form.

2.	Double-click the Value column for the Color property or one of the other properties listed below that use the Color editor.

Basic Colors grid

Displays selection of standard colors. Click a color to apply it to the selected component.

Custom Colors grid

Displays the colors that you have created. You can create custom colors by clicking Define Custom Colors.

Define Custom Colors

Click Define Custom Colors to expand the Color editor to show options that enable you to create your own colors.

Color field

Displays the spectrum of available colors. The crosshairs indicate the current color. For example, the crosshairs look like this when the color is a shade of yellow:

Click anywhere or drag in the color field to select a color. When you select a color here and then click Add To Custom Color, the selected color is added to one of the Custom Color boxes so you can use it again.

Color|Solid

Displays the currently selected color and its closest solid color. Double-click the solid color to make it the current color.

Hue

Enter a value for the hue. Hue is the "actual" color, for example, red, yellow-green, or purple. Hue refers to the color without regard to saturation or brightness (luminosity).

Sat(uration)

Enter a value for the saturation. Saturation refers to how much gray is in the color. The Sat(uration) field shows the saturation from 0 (medium gray) to 240 (pure color).

Note:	Saturation affects how clear the color is. Luminosity affects how bright the color is.

Lum(inosity) and the Luminosity Slider Control

Enter a value for the luminosity, or drag the pointer on the slide to set the luminosity. Luminosity is the brightness of a color. The Lum(inosity) field shows the luminosity from 0 (black) to 240 (white). The column to the right of the color field shows the range of luminosity for the current color. Slide the arrow to the right of the column up or down to adjust the luminosity. When you change the luminosity, the Red/Green/Blue color values also change.

Red/Green/Blue

Enter values for the proportion of red, green, and blue you want in your color. The values in these fields show the balance of red, green, and blue in the current color. This is sometimes called the RGB color. The range of available values for an RGB color is 0 to 255.

Add To Custom Colors

Click to add the color you have defined to the Custom Color grid on the Color editor.


Following section followed the first para in the Insert Object dialog box topic, but have jumps to ObjClass and ObjDoc property which do not appear to be in the VCL.

To open the Insert Object dialog box,

1.	Place an OLEContainer component on the form.

2.	With that component selected, right click to display the speed menu and select Insert Object.


Insert Object dialog box
Insert Object dialog box1042021

Use the Insert Object dialog box at design time to insert an OLE object into an OLEContainer component. The OLEContainer component enables you to create applications that can share data with an OLE server application. After you insert an OLE server object in your application, you can double-click the OLEContainer component to start the server application.

Select whether or not you want to create a new file for the chosen OLE server or use an existing file. If you use an existing file, it must be associated with an application that can be used as an OLE server.

Create New

If selected Object Type is also displayed.

Object Type

Select an application that you want to use as the OLE server. This list box displays all available applications that can be used as an OLE server. After you select an application, Delphi launches that application.

Create From File Radio

If selected File, Browse and Link are also displayed.

File

Enter the fully qualified path for the file you want to insert into your application. The file you choose must be associated with an application that can be used as an OLE server.

Browse

Click Browse to display the Browse dialog box, where you can select a file to use as the OLE server.

Link

Check Link to link the object on the form to a file. When an object is linked, it is automatically updated whenever the source file is modified. When Link is unchecked, you are embedding the object, and changes made to the original are not reflected in your container.

Display As Icon

Check to display the inserted object as an icon on the form. When this option is checked, the Change Icon button is displayed.

Change Icon

Click Change Icon to open the Change Icon dialog box, where you can specify an icon and label for the object you inserted onto the form.


Browse dialog box
Browse dialog box1042022

The Browse dialog box has multiple uses depending on where you open it. You can use the Browse dialog box for either of the following:

To load an existing file into the OLE container. The file you select must be associated with an application that can be used as an OLE server.

To select an icon to represent an OLE object on the form.

To open the Browse dialog box, do one of the following:

Click Browse in the Insert Object dialog box when you have Create From File selected.

Click Browse in the Change Icon dialog box.

Dialog box options

Source

Enter the name of the file you want to load or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the Source edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose the type of file you want to use as the OLE server. By default all files in the current directory are displayed in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the Source edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


Change Icon dialog box
Change Icon dialog box1042023

Use the Change Icon dialog box to specify an icon and a label for the object you are placing on the form.

To open the Change Icon dialog box,

1.	On the Insert Object dialog box, check Display As Icon.

2.	Click Change Icon.

Icon Radio

Select which icon you want to use. There are three options:

Option	When selected

Current	Uses the current icon.

Default	Uses the default icon.

From File	Enables you to specify an icon using a fully qualified path name. If you do not know the icon name or the path, click Browse to open the Browse dialog box. The display box below the edit box shows all the available icons in the specified file. To choose an icon, select it.

Label

Enter a label that will appear below the icon on the form.

Browse

Click Browse to open the Browse dialog box, where you can select an icon to represent the inserted object on the form.

Sample Icon display

Displays how the icon and label will appear on the form.


Paste Special dialog box
Paste Special dialog box1042024

Use the Paste Special dialog box to insert an object from the Windows Clipboard into your OLE container.

Source label

Displays the path of the file you are going to paste.

Paste/Paste Link Radio

Select Paste to embed the object on the form. When you embed an object on a form, your container application stores all the information for the object. It is not necessary to have an external file.

Select Paste Link to link the object to the form. When you link an object to a form, the main source is stored in a file so that when you update the object, the source file is also updated.

As

Lists the type of application object you are pasting. The application listed is the source application from which you received the object that you are pasting.


DDE Info dialog box
DDE Info dialog box1042025

See also

Use the DDE Info dialog box to specify, at design time, a DDE server application and a topic for a DDE conversation.

To open the DDE Info dialog box,

1.	Place a DDEClientConv component on the form.

2.	With the component selected, do one of the following:

Click the ellipsis button in the Value column for the DdeService property or DdeTopic property.

Double-click the Value column for the DdeService property or DdeTopic property.

Dialog box options

Dde Service

Specify the server application for the DDE conversation. The application you specify is entered into the Value column for the DdeService property.

You do not need to specify an extension for the server application.

If the directory containing the application is not on your path, you need to specify a fully qualified path.

Dde Topic

Enter the topic for a DDE conversation. The topic is a unit of data, identifiable to the server, containing the linked text. For example, the topic could be the file name of a Quattro Pro spreadsheet.

When the server is a Delphi application, the topic is the name of the form containing the data you want to link.

If the directory containing the topic is not on your path, you need to specify a fully qualified path.

Paste Link

Click Paste Link to paste the application name and file name from the contents of the Clipboard into the App and File edit boxes.

This button is active only when the Clipboard contains data from an application that can be a DDE server.


See also1042026

Creating DDE client applications

DDE conversations

Establishing a link with a DDE server


Filter editor
Filter editor1042027

See also

Use the Filter editor to define filters for the OpenDialog component and the SaveDialog component. These common dialog boxes use the value of Filters in the List Files Of Type combo box to display certain files in the Files list box.

Use the Filter editor to edit the Filters property.

To open the Filter editor,

1.	Place an OpenDialog component or SaveDialog component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for the Filters property.

Double-click the Value column for the Filters property.

Filter Name column

Enter the name of the filter you want to appear in the Files Of Type combo box.

Filter column

Enter wildcards and extensions that will define your filter. For example, *.TXT would display only files with the .TXT extension.

To apply multiple file extensions to your filter, separate them using a semicolon (;).


See also1042028

TOpenDialog component

TSaveDialog component


Select Directory dialog box
Select Directory dialog box (ReportSmith)1042029

See alsoThe Report component is included for compatibility purposes only.  The Quick Report components contained on the QReport tab of the component palette extend the capabilities of the Report component.

Use the Select Directory dialog box to choose a directory from which you can load or store a ReportSmith report.

Use the Select Directory dialog box to edit the ReportDir property for the Report component.

To open the Select Directory dialog box,

1.	Place a Report component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for the ReportDir property.

Double-click the Value column for the ReportDir property.

Dialog box options

Directory Name label

Displays the fully qualified path name of the current directory.

Directories

Select a directory where you want to store or load a report. In the current directory, all the files are displayed in the Files list box.

Files

Displays all the files in the current directory selected in the Directories list box. These files are dimmed.

Drives

Select an active drive. The directory structure for the selected drive appears in the Directories list box.

Network

If you are running under Windows for Workgroups or Windows NT, you can click the Network button to open the Connect Network Drive dialog box.


See also1042030

TReport component


Open dialog box
Open dialog box1042031

See also

Use the Open dialog box at design time to load a report into the Report component or a multimedia file into the MediaPlayer component.

To open the Open dialog box,

1.	Place a Report component or a MediaPlayer component on the form.

2.	With that component selected, do one of the following:

Click the ellipsis button in the Value column for any of the properties listed below.

Double-click the Value column for either of the properties listed below.

Dialog box options

File Name

Enter the name of the file you want to load or wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose the type of file you want to load. When you are loading a report, the default file extenstion is .RPT. When you are loading a multimedia file, all files in the current directory are displayed. However, you can limit the display to wave files, midi files, or Windows video files.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


See also1042032

TReport component

TMediaPlayer component


Loading an image at design time
Loading an image at design time1042033

Use the Delphi Picture editor to load images onto any of several graphic-compatible components and to specify an icon to represent a form when it is minimized at run time.

Each graphic-compatible component has a Glyph property that uses the Delphi Picture editor.

To load an image at design time,

1.	Add a graphic-compatible component to your form.

2.	To automatically resize the component so that it fits the graphic, set the component's AutoSize property to True before you load the graphic.

3.	In the Object Inspector, select the Glyph property.

4.	Either double-click in the Value column, or choose the ellipsis button to open the Picture editor.

(To open the Picture editor from an Image component, you can also double-click the component in the form.)

5.	Choose the Load button to open the Load Picture dialog box.

6.	Use the Load Picture dialog box to select the image you want to display, then choose OK.

The image you choose is displayed in the Picture editor.

7.	Choose OK to accept the image you have selected and exit the Picture Editor dialog box.

The image appears in the component on the form.

Note:	When loading an graphic into an Image component, you can automatically resize the graphic so that it fits the component by setting the Image component's Stretch property to True. (Stretch has no effect on the size of icon (.ICO) files.)


Viewing nested properties
Viewing nested properties1042034

Properties can have properties of their own, called nested properties. For example, the Font property of the Label component has nested properties, one of which is Style; the Style property in turn has its own nested properties.

Properties with nested properties show a plus (+) sign on their left side in the Object Inspector. You need to view these nested properties to set them.

To view nested properties,

Choose one of the following methods:

Double-click any property with a plus sign next to it.

The plus sign next to the top-level property changes to a minus (-) sign, and the nested properties are displayed.

To hide nested properties,

Double-click a property with a minus sign next to it.


Working with text
Working with text1043001

See also

Almost all applications manipulate text in some manner, ranging from providing word-processing capabilities to the user to simply displaying text in a label or menu item that the user can't modify.

The Delphi Memo and Edit components enable the user to read and write text at run time.

Choose a topic for more information.

Displaying and editing text in a memo control

Setting text alignment and word wrap

Using the Clipboard with text


See also1043002

Displaying and editing text in a Memo control

Displaying and editing fields in an edit box

Setting component properties.

TDBMemo component

TDBEdit component


Setting text alignment and word wrap
Setting text alignment and word wrap1043003

See also

Alignment and WordWrap are properties of the Memo component. As with all properties, you can set their values during run time with a simple assignment statement.

The following topics discuss ways to set text alignment and word wrap at run time.

Setting text alignment

Setting word wrap


See also1043004

Displaying and editing text in a memo control


Setting text alignment
Setting text alignment1043005

See also

You set the initial text alignment at design time by setting the component's Alignment property. You can also let your users specify the type of text alignment they prefer at run time.

The following code refers to a menu item called Text that contains commands for Left, Right, and Center alignment. The code specifies that when the Left menu item receives the Click event, the text in the memo field gets aligned to the left, and the Left command gets checked in the menu.

procedure TForm1.AlignLeft;

begin

   MemoLeft.Checked := True;

   MemoRight.Checked := False;

   EditCenter.Checked := False;

   Memo1.Alignment := taLeft;

end;

Only one menu command should be checked at any time, so the previous code ensures that the other commands are unchecked.


See also1043006

Setting word wrap

Displaying and editing text in a memo control


Setting word wrap
Setting word wrap1043007

See also	Example

The WordWrap property is True by default for the Memo component. The Memo can contain both vertical and horizontal scroll bars, which is the setting you might choose if word wrap were False. Word Wrap is often set as a toggle at run time.

You set the initial value of the ScrollBars property for a Memo component at design time. You might change the ScrollBars property at run time depending on the Memo.WordWrap setting. The example code illustrates one way to accomplish this.


See also1043008

Setting text alignment

Displaying and editing text in a memo control


Example1043009

The following example uses a Character menu with a Word Wrap item that the user can change dynamically to turn word wrap on and off. A check mark next to the menu item indicates that word wrap is on.

The OnClick event handler sets the value of the Memo component's WordWrap property as a toggle. Whenever the user selects the Word Wrap command, the value of the WordWrap property changes to its inverse. If WordWrap was True, it becomes False; if False, it becomes True.

The event handler adds either vertical scroll bars or both vertical and horizontal scroll bars to the Memo component based on the value of the WordWrap property.

Finally, it sets the Checked property to the value of the WordWrap property: if WordWrap is True, then the Checked property is also set to True. Checked is a Boolean property for menu items: If True, a check mark appears next to that menu item.

procedure TEditForm.SetWordWrap(Sender: TObject);

begin

  with Memo1 do

  begin

    WordWrap := not WordWrap;

    if WordWrap then

      ScrollBars := ssVertical else

      ScrollBars := ssBoth;

    WordWrap1.Checked := WordWrap;

  end;

end;


Using the clipboard with text
Using the Clipboard with text1043010

See also

Most text-handling applications provide users with a way to move selected text between documents, including documents in different applications. The Clipboard object in Delphi encapsulates the Windows Clipboard and includes methods that provide the basis for operations such as cutting, copying, and pasting text (and other formats).

The Clipboard object is declared in the Delphi Clipbrd unit. Before you can access methods declared in the Clipboard object, you need to add Clipbrd to the uses clause of any units that will use those methods.

Choose from the following topics for more information:

Selecting text

Cutting, copying, and pasting text

Deleting text


See also1043011

Using the Clipboard with graphics

Displaying and editing text in a memo control


Selecting text
Selecting text1043012

See also	Example

Before you can send any text to the Clipboard, the text must be selected. The function of reading and displaying selected text is native to the Memo and Edit components. In other words, you don稚 need to write code so that the Memo component can display selected text; it comes with this behavior.

The Stdctrls unit in Delphi provides several methods to work with selected text. (Recall that Delphi automatically adds the Stdctrls unit to the uses clause of any unit whose form contains a component declared within Stdctrls.) SelText, a run-time only property, contains a string based on any text selected in the component. The SelectAll method selects all the text in the memo or other component. The SelLength and SelStart properties return values for a selected string's length and starting position, respectively.


See also1043013

Cutting, copying, and pasting text

Deleting text

Using the Clipboard with text

Displaying and editing text in a memo control


Example1043014

The following code selects all text in a memo component. This could be an event handler, for example, for a Select All menu item.

procedure TEditForm.SelectAll(Sender: TObject);

begin

  Memo1.SelectAll;

end;


Cutting, copying, and pasting text
Cutting, copying, and pasting text1043015

See also	Example

The following methods cut, copy, and paste text:

CutToClipboard cuts selected text from a memo or edit field and also places it on the Clipboard.

CopyToClipboard copies all selected text in a memo or edit field to the Clipboard.

PasteFromClipboard copies all text currently on the Clipboard back to the location of the insertion point.


See also1043016

Selecting text

Deleting text

Using the Clipboard with text

Displaying and editing text in a memo control


Example1043017

The following OnClick event handlers cut, copy, and paste selected text from a memo component to the Clipboard. These event handlers could be used on an Edit menu for the Cut, Copy, and Paste commands.

procedure TEditForm.CutToClipboard(Sender: TObject);

begin

  Memo1.CutToClipboard;

end;

procedure TEditForm.CopyToClipboard(Sender: TObject);

begin

  Memo1.CopyToClipboard;

end;

procedure TEditForm.PasteFromClipboard(Sender: TObject);

begin

  Memo1.PasteFromClipboard;

end;


Deleting text
Deleting text1043018

See also	Example

The ClearSelection method provides you with a way to remove selected text from a memo component without copying the selected text to the Clipboard.

Contrast this with the CutToClipboard method, which deletes selected text and also copies it to the Clipboard.


See also1043019

Selecting text

Cutting, copying, and pasting text

Using the Clipboard with text

Displaying and editing text in a memo control


Example1043020

The following event handler deletes selected text from a memo component without copying the text selection onto the Clipboard.

procedure TEditForm.Delete(Sender: TObject);

begin

  Memo1.ClearSelection;

end;


SQL モニタ
SQL モニタ1045001

SQL モニタを使うと，SQL Link を介したリモートサーバーへの SQL 文，あるいは ODBC ソケットを介した ODBC データソースへの SQL 文の実際の呼び出しを見ることができます。

［SQL モニタ］を開くには

［データベース(D)｜SQL モニタ(S)］を選択します。

［分類］ペイン

さまざまな種類の動作をモニタできます。［オプション(O)｜トレースオプション(O)］を選択して［トレースオプション］ダイアログボックスを開き，［分類］ペインでモニタする動作のカテゴリを選択します。次のカテゴリの中からいくつでもモニタできます。

カテゴリ	表示

準備された問い合わせ文(P)	サーバーに送るために準備された文

実行された問い合わせ文(E)	サーバーが実行する文。準備されるのは 1 回に 1 つの文。ただし，異なるパラメータで 1 つの文が複数回実行されることがあるので注意が必要。

Input Parameters	INSERT または UPDATE を実行する場合にサーバーに送られるパラメータデータ

Fetched Data	サーバーから取り出されたデータ

動作(S)	ALLOCATE，PREPARE，EXECUTE，FETCH などの実行される各処理

コネクト/ディスコネクト(C)	データベースの接続と切断に関連する処理。サーバー側の必要に応じて，接続ハンドルの割り当て，接続ハンドルの解放が含まれる

トランザクション(T)	BEGIN，COMMIT，ROLLBACK (ABORT) などのトランザクション処理

BLOB入出力(L)	GET BLOB HANDLE，STORE BLOB などの BLOB データ型に対する処理

その他(M)	ほかのカテゴリに分類されない処理

ベンダーエラー(V)	サーバーが返したエラーメッセージ。サーバーによってエラーメッセージにエラーコードが含まれる場合がある

ベンダーＡＰＩ呼び出し(N)	サーバーに対する実際の API 関数呼び出し。たとえば Oracle での ORLON，InterBase での ISC_ATTACH_DATABASE()

［バッファ］ペイン

［バッファサイズ(S)］

トレース結果を保存しておくバッファの大きさを 256KB から 2048KB までキロバイト（KB）単位で指定できます。

［バッファ管理］

バッファからあふれたトレース記録をどのように扱うかを指定します。

［メモリ上(C)］	バッファの最後まで達すると先頭に戻り記録を続けます。古い記録は捨てられます。

［ディスクに書き出し］	バッファからあふれた記録は指定されたファイルに書き込まれます。記録を残すためのファイルの名前を［ファイル名(F)］に記述するか，［参照(B)］ボタンを押してファイルを選択することができます。


Working with string lists
Working with string lists1046001

See also

There are numerous occasions when a Delphi application needs to deal with lists of character strings. Among these lists are the items in a list box or combo box, the lines of text in a memo field, the list of fonts supported by the screen, the names of the tabs on a notepad, the items in an outline, and a row or column of entries in a string grid.

Although applications use these lists in various ways, Delphi provides a common interface to all of them through an object called a string list, and goes even farther by making them interchangeable, meaning you can, for example, edit a string list in a memo field and then use it as the list of items in a list box.

You have probably already used string lists through the Object Inspector. A string-list property appears in the Object Inspector with [TStrings] in the Value column. When you double-click [TStrings], you get the String List editor, where you can edit, add, or delete lines.

You can also work with string lists at run time. These are the most common types of string-list tasks:

Manipulating the strings in a list

Loading and saving string lists

Creating a new string list

Adding objects to a string list

Operating on objects in a string list


See also1046002

Creating an owner-draw control


Manipulating the strings in a list
Manipulating strings in a list1046003

See also

Quite often in a Delphi application, you need to write code to work with strings in an existing string list. The most common case is that some component in the application has a string-list property, and you need to change it or get strings from it.

These are the common operations you might need to perform:

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Adding a string

Moving a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


See also1046004

Loading and saving string lists

Creating a new string list

Adding objects to a string list

Operating on objects in a string list


Counting the strings in a list
Counting the strings in a list1046005

See also	Example

To find out how many strings are in a string list, use the Count property.

Count is a read-only property that indicates the number of strings in the list. Since the indexes used in string lists are zero-based, Count is one more than the index of the last string in the list.


See also1046006

Accessing a particular string

Finding the position of a string

Adding a string

Moving a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


Example1046007

The following example returns the number of different fonts the current screen supports.

FontCount := Screen.Fonts.Count;


Accessing a particular string
Accessing a particular string1046008

See also	Example

Each string list has an indexed Strings, property which you can treat like an array of strings. For example, the first string in the list is Strings[0].

Since the Strings property is the most common part of a string list to access, Strings is the default property of the list, meaning that you can omit the Strings identifier and just treat the string list itself as an indexed array of strings.

To access a particular string in a string list,

Refer to it by its ordinal position, or index, in the list.

The string numbers are zero-based, so if a list has three strings in it, the indexes cover the range 0..2.

To determine the maximum index,

Check the Count property.

If you try to access a string outside the range of valid indexes, the string list raises an exception.


See also1046009

Counting the strings in a list

Finding the position of a string

Adding a string

Moving a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


Example1046010

The following examples both set the first line of text in a memo field to be "This is the first line."

Memo1.Lines.Strings[0] := 'This is the first line.';

Memo1.Lines[0] := 'This is the first line.';


Finding the position of a string within a list
Finding the position of a string within a list1046011

See also	Example

If you have a list of strings, you can easily determine its position in a string list, or whether it is even in the list.

To locate a string in a string list,

Use the string list's IndexOf method.

IndexOf takes a string as its parameter, and returns the index of the matching string in the list, or -1 if the string is not in the list.

Note:	IndexOf works only with complete strings. That is, it must find an exact match for the whole string passed to it, and it must match a complete string in the list. If you want to match partial strings (for instance, to see if any of the strings in the list contains a given series of characters), you need to iterate the list yourself and compare the strings.


See also1046012

Counting the strings in a list

Accessing a particular string

Adding a string

Moving a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


Example1046013

The following example uses IndexOf to determine whether a given file name is in the list of files in a file list box:

if FileListBox1.IndexOf('AUTOEXEC.BAT') > -1 then { you're in the root directory };


Adding a string to an existing list
Adding a string to an existing list1046014

See also	Example

There are two ways to add a string to a string list:

Add it to the end of the list

Insert it in the middle of the list

To add a string to the end of the list,

Call the Add method, passing the new string as the parameter. The added string becomes the last string in the list.

To insert a string into the list,

Call the Insert method, passing two parameters: The index where you want the inserted string to appear, and the string.

If the list does not already have at least two strings, you will get an index-out-of-range exception.


See also1046015

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Moving a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


Example1046016

The following example inserts the string 'Three' as the third string in a list:

Insert(2, 'Three');

Note:	If the list doesn't already have at least two strings, Delphi raises an index-out-of-range exception.


Moving a string within a list
Moving a string within a list1046017

See also	Example

You can move a string to a different position in a string list, such as when you want to sort the list. If the string has an associated object, the object moves with the string.

To move a string in the list,

Call the Move method, passing two parameters: the current index of the item and the index where you want to move the item to.


See also1046018

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Adding a string

Deleting a string

Copying a complete string list

Iterating the strings in a list


Example1046019

The following example moves the third string in a list to the fifth position.

Move(3, 5);


Deleting a string from a list
Deleting a string from a list1046020

See also	Example

When you have an existing list of strings, you might often want to remove a string from that list.

To delete a string from a string list,

Call the string list's Delete method, passing the index of the string you want to delete.

If you do not know the index of the string you want to delete, use the IndexOf method to locate it.

To delete all the strings in a string list,

Use the Clear method.


See also1046021

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Adding a string

Moving a string

Copying a complete string list

Iterating the strings in a list


Example1046022

The following example uses IndexOf to determine the location of a string in a list, and deletes that string if present:

with ListBox1.Items do

begin

  if IndexOf('bureaucracy') > -1 then

    Delete(IndexOf('bureaucracy'));

end;


Copying a complete string list
Copying a complete string list1046023

See also	Example

Copying the strings from one list to another overwrites the strings that were originally in the destination list.

To copy a list of strings from one string list to another,

Assign the source list to the destination list.

Even if the lists are associated with different kinds of components (or no components at all), Delphi handles the copying of the list for you.

However, sometimes you want to append a new string list to an existing list.

To add a list of strings to the end of another list,

Call the AddStrings method, passing as a parameter the list of strings you want to add.


See also1046024

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Adding a string

Moving a string

Deleting a string

Iterating the strings in a list


Examples1046025

The following example copies the items from a combo box into an outline:

Outline1.Lines := ComboBox1.Items;

The following example adds all the items from the combo box to the end of the outline:

Outline1.AddStrings(ComboBox1.Items);


Iterating the strings in a list
Iterating the strings in a list1046026

See also	Example

Many times you need to perform an operation on each string in a list, such as searching for a particular substring or changing the case of each string.

To iterate through each string in a list,

Use a for loop with an Integer-type index. Inside the loop you can access each string and perform the desired operation.

The loop should run from zero up to one less than the number of strings in the list (Count - 1).


See also1046027

Counting the strings in a list

Accessing a particular string

Finding the position of a string

Adding a string

Moving a string

Deleting a string

Copying a complete string list


Example1046028

The following example iterates the strings in a list box and converts each one to all uppercase characters in response to a button click:

procedure TForm1.Button1Click(Sender: TObject);

var

  Index: Integer;

begin

  for Index := 0 to ListBox1.Items.Count - 1 do

    ListBox1.Items[Index] := UpperCase(ListBox1.Items[Index]);

end;


Loading and saving string lists
Loading and saving string lists1046029

See also	Example

You can easily store any Delphi string list in a text file and load it back again (or load it into a different list).

You can also use the same mechanism to save lists of items for list boxes or complete outlines.

To load a string list from a file,

Call the LoadFromFile method and pass the name of the text file to load from.

LoadFromFile reads each line from the text file into a string in the list.

To store a string list in a text file,

Call the SaveToFile method and pass it the name of the text file to save to.

If the file does not already exist, SaveToFile creates it. Otherwise, it overwrites the current contents of the file with the strings from the string list.


See also1046030

Manipulating the strings in a list

Creating a new string list

Adding objects to a string list

Operating on objects in a string list


Example1046031

The following example loads a copy of the AUTOEXEC.BAT file from the root directory of the C drive into a memo field and makes a backup copy called AUTOEXEC.BAK:

procedure TForm1.FormCreate(Sender: TObject);

var

  FileName: string;	{ storage for file name }

begin

  FileName := 'C:\AUTOEXEC.BAT';	{ set the file name }

  with Memo1 do

  begin

    LoadFromFile(FileName);	{ load from file }

    SaveToFile(ChangeFileExt(FileName, 'BAK'));	{ save into backup file }

  end;

end;


Creating a new string list
Creating a new string list1046032

See also

Most of the time when you use a string list, you use one that is part of a component, so you do not have to construct the list yourself. However, you can also create standalone string lists that have no associated component. For instance, your application might need to keep a list of strings for a lookup table.

When you create your own string list you must remember to free the list when you finish with it. There are two distinct cases you might need to handle:

A list that the application creates, uses, and destroys all in a single routine

A list that the application creates, uses throughout run time, and destroys before it shuts down

The way you create and manage a string list depends on the string list type. It can be either of the following:

Long-term string lists

Short-term string lists


See also1046033

Manipulating the strings in a list

Loading and saving string lists

Adding objects to a string list

Operating on objects in a string list


Short-term string lists
Short-term string lists1046034

See also	Example

Short-term string lists are useful if you need to use a string list only for the duration of a single routine. You can create it, use it, and destroy it all in one place. This is the safest way to use string list objects.

Because the string list object allocates memory for itself and its strings, it is important that you protect the allocation by using a try..finally block to ensure that the object frees its memory even if an exception occurs.

The basic outline of the use of a short term string list, then, is to

1.	Construct the string-list object.

2.	In the try part of a try..finally block, use the string list.

3.	In the finally part, free the string-list object.


See also1046035

Long-term string lists


Example1046036

The following event handler responds to a click on a button by constructing a string list, using it, and then destroying it again.

procedure TForm1.Button1Click(Sender: TObject);

var
  TempList: TStrings;	{ declare the list }

begin

  TempList := TStringList.Create;	{ construct the list object }

  try
    { use the string list }

  finally
    TempList.Free;	{ destroy the list object }

  end;

end;


Long-term string lists
Long-term string lists1046037

See also	Example

Long-term string lists are useful when you need a string list that is available at any time while your application runs. You need to construct the list when the application is first executed, then destroy it before the application terminates.

To create a string list that is available throughout run time,

1.	Add a field of type TStrings to the application's main form object, giving it the name you want to use.

2.	Create a handler for the main form's OnCreate event. The create-event handler is executed before the form appears onscreen at run time.

3.	In the create-event handler, construct the string-list object.

4.	Create a handler for the main form's OnDestroy event. The destroy-event handler is executed just after the main form disappears from the screen before the application stops running.

Any other event handlers can then access the string list by the name you declared in the first step.


See also1046038

Short-term string lists


Example1046039

The following example adds a string to the list named ClickList. The click-event handler for the main form adds a string to the list every time the user presses a mouse button, and the application writes the list out to a file before destroying the list.

unit Unit1;

interface

uses WinTYpes, WinProcs, Classes, Graphics, Forms, Controls, Apps;

type

  TForm1 = class(TForm)

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

  private

    { Private declarations }

  public

    { Public declarations }

    ClickList: TStrings;	{declare the field}

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

begin

  ClickList := TStringList.Create;	{construct the list}

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

  ClickList.SaveToFile(ChangeFileExt(Application.ExeName, '.LOG'));

{save the list}

  ClickList.Free;	{destroy the list object}

end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  ClickList.Add(Format('Click at (%d, %d)', [X, Y]));	{add a

string to the list}

end;

end.


Adding objects to a string list
Adding objects to a string list1046040

See also	Example

In addition to its list of strings, stored in the Strings property, a string list can also have a list of objects, which it stores in its Objects property. Like Strings, Objects is an indexed property, but instead of an indexed list of strings, it is an indexed list of objects.

If you are just using the strings in the list, it does not matter whether you have objects: The list does nothing with the objects unless you specifically access them. Also, it does not matter what kind of object you assign to the Objects property. Delphi just holds the information; you manipulate it as you need to.

Note:	Some string lists do not allow objects, because it does not make sense to have them. For example, the string lists representing the lines in a memo or the pages in a notebook cannot have associated objects.

To associate an object with an existing string,

Assign the object to the Objects property at the same index.

Although you can assign any type of objects you want to Objects, the most common use is to associate bitmaps with strings for owner-draw controls. The important thing to remember is that strings and objects in a string list work in pairs. For every string, there is an associated object, although by default, that object is nil.

It is also important to understand that the string list does not own the objects associated with it. That is, destroying the string-list object does not destroy the objects associated with the strings.


See also1046041

Creating an owner-draw control

Operating on objects in a string list


Operating on objects in a string list
Operating on objects in a string list1046042

See also

For every operation you can perform on a string list with a string, you can perform a corresponding operation with a string and its associated object. For example, you can access a particular object by indexing into the Objects property, just as you would the Strings property. The biggest difference is that you cannot omit the name Objects, since Strings is the default property of the string list.

The following table summarizes the properties and methods you use to perform corresponding operations on strings and objects in a string list.

Operation	For strings	For objects

Access an item	Strings property	Objects property

Add an item	Add method	AddObject method

Insert an item	Insert method	InsertObject method

Locate an item	IndexOf method	IndexOfObject method

Methods such as Delete, Clear and Move operate on items as a whole. That is, deleting an item deletes both the string and the corresponding object. Also note that the LoadFromFile and SaveToFile methods operate on only the strings, since they work with text files.

Accessing associated objects

You access objects associated with a string list just as you access the strings in the list. For example, to get the first string in a string list, you access the string list's Strings property at index 0: Strings[0]. The object corresponding to that string is Objects[0].


See also1046043

Creating an owner-draw control

Adding objects to a string list


Example1046044

The following example associates a bitmap called AppleBitmap with the string 'apple' in the string list named Fruits.

with Fruits do Objects[IndexOf('apple')] := AppleBitmap;

You can also add objects at the same time you add the strings, by calling the string list's AddObject method instead of Add, which just adds a string. AddObject takes two parameters, the string and the object. For example,

Fruits.AddObject('apple', AppleBitmap);


Viewing pages in the Code Editor
Viewing pages in the Code Editor1047001

See also

When a page of the Code Editor is displayed, you can scroll through all the data it contains, not just particular sections of your code.

To view a page in the Code Editor, choose one of the following methods:

Click the tab for the page you want to view.

Press Ctrl+Tab to go forward through the Editor pages, and Shift+Ctrl+Tab to go backward.

Select a unit from the View Unit dialog box. To open the View Unit dialog box, choose View|Unit.

When the Code Editor is displayed, you can return to a form at any time using either of these methods:

To return to the form,

Click any part of the form that is visible under the Code Editor.

Choose View|Form to open the View Form dialog box, and choose the form you want to view.

Use SpeedBar buttons to display the current form, or to open the View Form dialog box.


See also1047002

Code Editor

Locating an event handler that's not the default

Deleting event handlers


Using the sender parameter
Using the Sender parameter1047003

See also	Example

The Sender parameter in an event handler informs Delphi which component received the event, and therefore called the handler. You can write a single event handler that responds to multiple component events by using the Sender parameter in an if..then..else statement.


See also1047004

Associating an event with an existing event handler

Displaying and coding shared events

Displaying and coding shared component events


Example1047005

The following code either displays the title of the application in the caption of a modal dialog box, or else displays nothing, depending on whether the OnClick event was received by Button1 or by another button using the same event handler.

procedure TMain1.Button1Click(Sender: TObject);

begin

if Sender = Button1 then

  AboutBox.Caption := 'About ' + Application.Title

else AboutBox.Caption := 葬;

AboutBox.ShowModal;

end;


Displaying shared events
Displaying and coding shared events1047006

See also

There are many events, such as the OnClick event, that are available to more than one component. When components have events in common, you can associate the common event with an event handler (existing or new) without having to do this separately for each component.

You do this by first displaying the shared event, and then creating an event handler for it.

To display shared events,

1.	In the form, select all the components whose common events you want to view.

2.	Display the Events page of the Object Inspector.

The Object Inspector displays only those events that pertain to all the selected components. (Note also that only events in the current form are displayed.)

When you create a shared event handler (or when you reuse an existing one), Delphi does not duplicate the event handler code for every component event associated with it. You will see the code in the Code Editor only once, but the same code gets called whenever any of the component events occurs.

To associate a shared component event with an existing event handler,

1.	Select the components for which you want to associate a shared event handler.

2.	Display the Events page of the Object Inspector, and select an event.

The Object Inspector displays only those events that the selected components have in common.

3.	From the drop-down list next to the event, select an existing event handler, and press Enter.

Whenever any of the components you selected receives the specified event, the event handler you selected in called.

To create an event handler for a shared event,

1.	Select the components for which you want to create a shared event handler.

2.	Display the Events page of the Object Inspector, and select an event.

3.	Type a name for the new handler, and press Enter, or double-click the Handler column if you want Delphi to generate a name.

Delphi creates an event handler in the Code Editor, positioning the cursor in the begin..end block.

If you choose not to name the event handler, Delphi names it for you based on the order in which you selected the components.

4.	Type the code you want executed when the selected event occurs for any of the components.


See also1047007

Associating an event with an existing event handler

Generating the default event handler

Displaying and coding shared events

Locating an event handler that's not the default

Modifying a shared event handler

Deleting event handlers


Modifying the form's type declaration
Modifying the form's type declaration1047008

See also

When you add a component to a form, Delphi generates an instance variable, or field, for the component and adds it to the form's type declaration. Here is how adding a button changes the form's type declaration:

type

   TForm1 = class(TForm)

     Button1: TButton;	{this is the code Delphi adds}

   end;

Similarly, when you delete a component, Delphi removes the corresponding type declaration. You can view similar code being added or removed from the Code Editor.

To view code being added in the Code Editor,

1.	Click the form's Title bar and hold down the mouse button while you drag the form to a new location so you can see the entire Code Editor.

2.	Scroll in the Code Editor until the type declaration section is visible.

3.	Add a component to the form while watching what happens in the Code Editor.

4.	Delete the component, again while viewing the Code Editor.

Note:	Delphi does not remove any event handlers (or methods) associated with components you delete, because those event handlers might be called by other components in the form. You can still run your program so long as the method declaration and the method itself both remain in the unit file. If you delete the method without deleting its declaration, Delphi generates an 填ndefined forward� error message.


See also1047009

The Name property

Adding components to a form


Making a dialog box modal or modeless
Making a dialog box modal or modeless1048001

See also

Because dialog boxes are simply customized forms, they, like forms, can be either modal or modeless. Most dialog boxes are modal. When a form is modal, the user must explicitly close it before working in another form. When a form is modeless, it can remain onscreen while the user works in another form.

Any form you create can be used in your application modally, or modelessly.

To display a form in a modeless state,

Call its Show method.

Note:	If you want a modeless dialog box to remain on top of other windows at run time, set its FormStyle property to fsStayOnTop.

To display a form modally,

Call its ShowModal method.


See also1048002

Setting component properties

Building dialog boxes

Executing button code on Esc

Executing button code on Enter


Setting the tab order
Setting the tab order1048003

See also

Tab order is the order in which focus moves from component to component in a running application when the Tab key is pressed.

To enable the Tab key to shift focus to a component on a form,

Set the TabStop property of the component to True.

The tab order is initially set by Delphi, corresponding to the order in which you add components to the form. You can change this by changing the TabOrder property of each component, or by using the Edit Tab Order dialog box.

To use the Edit Tab Order dialog box,

1.	Select the form, or a container component in the form, that contains the components whose tab order you want to set.

2.	Choose Edit|Tab Order.

The Edit Tab Order dialog box appears, displaying a list of components ordered (first to last) in their current Tab order.

3.	In the Controls list, select a component and press the up or down arrow, or drag the component to its new location in the tab order list.

4.	When the components are ordered to your satisfaction, choose OK.

Using the Edit Tab Order dialog box changes the value of the components' TabOrder property. You can also do this manually, if you want.

To remove a component from the tab order,

Set the component's TabStop property to False.

When the user presses the Tab key in the running application, the focus will skip over this component and go to the next one in the tab order. This is true even if the component has a valid TabOrder value.

Note	Removing a component from the tab order does not disable the component.

To manually change a component's TabOrder property,

1.	Select the component whose position in the tab order you want to change.

2.	In the Object Inspector, select the TabOrder property.

3.	Change the TabOrder property's value to reflect the position you want the component to have in the tab order.

Note:	The first component in the tab order should have the TabOrder value of 0.

Keep in mind the following points when manually setting your tab order (if you are using the Edit Tab Order dialog box, you do not need to worry about them):

Each TabOrder property value must be unique. If you give a component a TabOrder value that has already been assigned to another component on this form, Delphi renumbers the TabOrder value for all other components accordingly.

If you attempt to give a component a TabOrder value equal to or greater than the number of components on the form (because numbering starts with 0), Delphi does not accept the new value, instead entering a value that ensures the component will be last in the tab order.

Components that are invisible or disabled are not recognized in the tab order, even if they have a valid TabOrder value. When the user presses Tab, the focus skips over such components and goes to the next one in the tab order. For more information, see Enabling and disabling components.

Testing the Tab Order

You can test the tab order by running the application. At design time, focus always moves from component to component in the order that the components were placed on the form. Changes you make to the tab order at design time are reflected only at run time.


See also1048004

Setting the focus in a dialog box

Enabling and disabling components

Building dialog boxes


Enabling and disabling components
Enabling and disabling components1048005

See also	Example

You often want to prevent a user from accessing certain components in a dialog box or form, either initially when the dialog box opens, or in response to changing conditions with the dialog box at run time.

To disable a component at design time,

Use the Object Inspector to set the value of the Enabled property  to False.

When a component is disabled, it appears dimmed, and the user cannot tab to it, even if its TabStop property is set to True.

Note:	Certain components also contain a ReadOnly property to restrict the kind of access a user has to the contents of the component at run time.

By disabling a component at design time, you specify that the component is initially unavailable to the user when the dialog box first opens. You can also dynamically change whether a component is enabled at run time.

To disable a component at run time,

Type the following code in an event handler for the component:

<componentn>.Enabled := False;

where <componentn> is the name of the component, for example, Button1.


Example1048006

The following event handler specifies that when the user clicks Button1, Button2 is disabled.

procedure TForm1.Button1Click(Sender: TObject);

begin

   Button2.Enabled := False

end;


See also1048007

Setting the tab order

Developing custom dialog boxes


Setting the component focus in a form
Setting the component focus in a form1048008

See also

Only one component per form can be active, or have the focus, in a running application at any given time. The button with focus in a form takes the OnClick event when the Enter key is pressed.

The component having initial focus in the form at run time corresponds to the ActiveControl property of the form.

If no component is specified as the active control, Delphi gives initial focus to any button component whose Default property is set to True.

If no button is specified as the default for the form, Delphi gives initial focus to the component that is first in the Tab Order, excluding:

Disabled components

Components that are invisible at run time

Components whose TabStop property is set to False

To specify the active component at design time,

Select the form's ActiveControl property and use the drop-down list to select the the component you want to have focus when the form first opens.

To change the active component during run time,

Call the SetFocus method from an event handler, for example,

<componentn>.SetFocus;

where <componentn> is the name of the component, for example, Button1.

Note:	If you set a button as the active component for the form at design time, that setting overrides, at run time, any default button you might have specified.


See also1048009

Setting the tab order

Developing custom dialog boxes


Providing command buttons
Providing command buttons1048010

See also

Depending on whether you intend to use your dialog box in a modal or modeless state, you might want to provide certain command buttons in the dialog box. For modal dialog boxes, you need to provide the user with a way to exit the dialog box. It痴 fairly standard design to provide one or more command buttons for this purpose. For simple modal dialog boxes, such as a message box, one button is often sufficient. Such a button might be labeled, for instance, 徹K� or 鼎lose.� (If you have another button in the dialog box labeled 哲o,� as described in the next paragraph, this button might be labeled 添es.�)

In cases where the dialog box accepts input from the user, you want to provide users with a choice of whether or not to process their input on exiting the dialog box. You can do this by means of an additional button labeled, for example, 鼎ancel� or 哲o.� (If your dialog box explicitly asks a question of the user, you might want to label this button 哲o�; otherwise, 鼎ancel� is usually more appropriate.)

Your code controls what happens when a user chooses a command button, for example, whether changes are processed or not.

By setting properties of the Button component, you can call a button痴 event-handler code when the user presses Enter or Esc; and you can specify that the dialog box close when the user chooses a command button, without writing any additional code. See the following topics for more information:

Executing button code on Esc

Executing button code on Enter

Note:	You can quickly create many standard command buttons by adding a BitBtn component to the form and setting its Kind property.


See also1048011

Setting the tab order

Setting the focus in a dialog box

Building dialog boxes


Executing button code on Esc
Executing button code on Esc1048012

See also

Delphi provides a Cancel property for Button components. When your form contains a button whose Cancel property is set to True, pressing the Esc key at run time executes any code contained in the button痴 OnClick event handler.

To designate a button as the Cancel button,

Set its Cancel property to True.

To specify that the modal dialog box close when the user chooses a Cancel button, set the button's ModalResult property to mrCancel.

Setting a button's ModalResult property to a nonzero value means the modal dialog box closes automatically when the user chooses the button.

You can also use the BitBtn component to create a Cancel button.

To use the bitmap button to create a Cancel button,

Add a BitBtn component to your form, and set its Kind property to bkCancel. This sets the button's Cancel property to True, and the ModalResult property to mrCancel.


See also1048013

Executing button code on Enter


Executing button code on Enter
Executing button code on Enter1048014

See also

When your form contains a button whose Default property is set to True, pressing Enter at run time executes any code contained in the button痴 OnClick event handler--unless another button has focus when the Enter key is pressed.

Even if your form contains a default button, another button can take focus away at run time. Pressing the Enter key calls the OnClick event handler code of the button with focus, overriding any other button痴 Default property setting. (The button with focus is indicated by a darker, thicker border than that of other buttons in the dialog box.)

Note:	Although other components in a form can have focus, only button components respond when the user presses Enter. The default button takes the OnClick event when another non-button component in the form has focus.

To specify a button as the default button,

Set its Default property to True.

To specify that the modal dialog box close when the user chooses a default button, set the button's ModalResult property to mrOK.

Setting a button's ModalResult property to a nonzero value means the modal dialog box closes automatically when the user chooses the button.

You can also use the BitBtn component to create a Default button.

To use the bitmap button to create a default button,

Add a BitBtn component to your form, and set its Kind property to bkOK. This automatically sets the button's Default property to True and the ModalResult property to mrOK.

To change focus at run time,

Call the button痴 SetFocus method.


See also1048015

Executing button code on Esc


Setting form properties for a dialog box
Setting form properties for a dialog box1048016

See also

By default, Delphi forms have Maximize and Minimize buttons, a resizable border, and a Control menu that provides additional commands to resize the form. While these features are useful at run time for modeless forms, modal dialog boxes seldom need them.

Delphi provides a BorderStyle property for the form that includes several useful values. Setting the form's BorderStyle to bsDialog implements the most common settings for a dialog box, such as:

Removing the Minimize and Maximize buttons

Providing a Control menu with only the Move and Close options

Making the form border non-resizeable, and giving it a "beveled" appearance

The following table shows other form property settings that can be used, individually or in concert, to create different form styles.

Property	Setting	Effect

BorderIcons

    biSystemMenu	False	Removes Control (System) menu

    biMinimize	False	Removes Minimize button

    biMazimize	False	Removes Maximize button

BorderStyle	bsSizeable	Enables the user to resize the form border

bsSingle	Provides a single outline, non-resizeable border

bsNone	No distinguishable border; not resizeable

bsDialog	Window has a border but not resizeable

bsToolWindow	Makes title bar small; window is not resizeable

bsSizeToolWindow	Makes title bar small; window is resizeable

Note:	Changing these settings does not change the design-time appearance of the form; these property settings become visible at run time.

When you remove the form's Control (or system) menu, you need to provide the user with a way to exit the dialog box. You can do this by including buttons in the form.

Specifying a caption for a dialog box

In most Windows-based applications, each dialog box has a caption on its Title bar that describes the primary function of the dialog box.

By default, Delphi displays the Name property value for each form in the form's Title bar. If you change the Name property of the form prior to changing the Caption property, the Title bar caption changes to the new name. Once you change the Caption property, the form's title bar always reflects the current value of Caption.


See also1048017

Developing custom dialog boxes


Testing the user interface
Testing the user interface1048018

See also

After you have spent some time designing forms and coding event handlers, you might want to test your user interface to see whether it responds as you want. For instance, you can check that the proper component has focus as the application begins running, that the tab order is correct, and so on. You do not need to have a fully functional application to test your work.

To run your application, choose one of the following methods:

Choose Run|Run.

Click the Run button on the SpeedBar.

This compiles and then executes your program.

To terminate your application, choose one of the following methods:

Double-click the form's Control-menu box.

Choose Run|Program Reset.


1048019


See also1048020

Component basics

Compiling, building, and running projects


Coding the window menu commands
Coding the Window menu commands1049001

See also

MDI applications should always include a Window (or other) menu item that contains Tile, Cascade, and Arrange Icons commands to offer users an easy way to arrange their open documents in the client area of the frame window.

To handle the clicks for the Tile, Cascade, and Arrange Icons menu commands, generate OnClick event handlers for each menu item, and call the Tile, Cascade, or ArrangeIcons method as appropriate.  For each event handler, you need write only one line of code--a method call--and Delphi does the rest for you.

For example:

procedure TFrameForm.Tile1Click(Sender: TObject);

begin

  Tile;

end;

procedure TFrameForm.Cascade1Click(Sender: TObject);

begin

  Cascade;

end;

procedure TFrameForm.ArrangeIcons1Click(Sender: TObject);

begin

  ArrangeIcons;

end;


See also1049002

Including a list of open documents in a menu

Arranging open child windows

Creating an MDI application


Displaying a list of open documents in a menu
Including a list of open documents in a menu1049003

See also

MDI applications should always include a menu item that contains a list of the open document windows, which lets users quickly switch among them. (The window that currently has focus appears in the list with a check mark next to it.)

You can add a list of open documents to any menu item that appears on a menu bar in the MDI form. This list can, but need not, be included on the Window menu -- for example, it could be on a File or View menu. However, there can be only one such list per menu bar. The list of open documents appears below the last item in the menu.

To include a list of open documents as part of a menu, set the frame form's WindowMenu property to the name (not the caption) of the menu under which you want the list to appear.

To include an open document list in a menu,

1.	Set the form style to fsMDIForm.

This makes the form an MDI frame.

2.	Create a menu for the MDI form that contains the menu item where you want the open document list to appear.

3.	Select the frame form, and then select the Properties page of the Object Inspector.

4.	From the drop-down list next to the WindowMenu property, select the name of the menu item under which you want the open document list to appear (for example, a Window or View menu.

This name must represent an item that appears on the menu bar, not a submenu item, because document lists cannot be used in nested menus.


See also1049004

Coding the window menu commands

Arranging open child windows

Creating an MDI application

Designing menus


Adding a separator bar to a menu
Adding a separator bar to a menu1050001

Enter a hyphen as the caption of the menu item.


Specifying keyboard shortcuts
Specifying keyboard shortcuts1050002

See also

Enter a value for the ShortCut property, or or select a key combination from the drop-down list. However, this list is only a subset of the valid combinations you can type in.

Keyboard shortcuts enable the user to perform the action without accessing the menu directly by typing the shortcut key combination.

Caution:	Delphi does not check for duplicate shortcut keys, you must track values you have entered in your application menus.


See also1050003

Adding, inserting, and deleting menu items

Adding, inserting, and deleting menu items and keyboard shortcuts


Editing menu items without opening the Menu Designer
Editing menu items without opening the Menu Designer1050004

See also

When you edit a menu item by using the Menu Designer, its properties are still displayed in the Object Inspector. You can switch focus to the Object Inspector and continue editing the menu item properties there. Or you can select the menu item from the Component list and edit its properties without ever opening the Menu Designer.

To edit a menu item without opening the Menu Designer,

Select the item from the Component list.

To close the Menu Designer window and continue editing menu items,

1.	Switch focus from the Menu Designer window to the Object Inspector by clicking the properties page of the Object Inspector.

2.	Close the Menu Designer as you normally would.

The focus remains in the Object Inspector, where you can continue editing properties for the selected menu item.

To edit another menu item, select it from the Component list.


See also1050005

Designing menus

Menu Designer SpeedMenu


Menu Designer SpeedMenu
Menu Designer SpeedMenu1050006

See also

The Menu Designer SpeedMenu provides quick access to the most common Menu Designer commands, and to the menu template options.

To display the Menu Designer SpeedMenu,

Choose one of the following methods:

Right-click anywhere on the Menu Designer.

Press Alt+F10 when the cursor is in the Menu Designer window.

The first three commands on the Menu Designer SpeedMenu directly perform an action.

Command	Action

Insert	Inserts a placeholder above or to the left of the cursor

Delete	Deletes the selected menu item (and all its sub-items, if any)

Create SubMenu	Creates a placeholder at a nested level and adds an arrow to the right of the selected menu item

The rest of the commands on the Menu Designer SpeedMenu open dialog boxes. Choose a command for more information.

Select Menu

Save As Template

Insert From Template

Delete Templates

Insert from Resource


See also1050007

Designing menus

Setting menu item properties by using the Object Inspector

Switching among menus at design time


Insert (Menu Designer SpeedMenu)
Insert (Menu Designer SpeedMenu)1050008

Choose Insert from the Menu Designer SpeedMenu to add a menu item placeholder before the selected menu item.


Delete (Menu Designer SpeedMenu)
Delete (Menu Designer SpeedMenu)1050009

Choose Delete from the Menu Designer SpeedMenu to remove the selected menu item.


Create Submenu (Menu Designer SpeedMenu)
Create Submenu (Menu Designer SpeedMenu)1050010

Choose Create Submenu from the Menu Designer SpeedMenu to insert a menu item placeholder to the right of the selected menu item and add an arrow to the selected item to indicate a nested level.


Select Menu (Menu Designer SpeedMenu)
Select Menu (Menu Designer SpeedMenu)1050011

See also

Choose Select Menu from the Menu Designer SpeedMenu to open the Select Menu dialog box.

Select Menu dialog box

Use this dialog box to quickly select from among the existing form menus.


See also1050012

Switching among menus at design time


Save As Template (Menu Designer SpeedMenu)
Save As Template (Menu Designer SpeedMenu)1050013

See also

Choose Save As Template from the Menu Designer SpeedMenu to open the Save Template dialog box, which enables you to save a menu for later reuse.

Save Template dialog box

Use this dialog box to save a menu for reuse.


See also1050014

Saving a menu as a template


Insert From Template (Menu Designer SpeedMenu)
Insert From Template (Menu Designer SpeedMenu)1050015

See also

Choose Insert From Template from the Menu Designer SpeedMenu to open the Insert Template dialog box.

Insert Template Dialog Box

Use this dialog box to add a predesigned menu to the active menu component.


See also1050016

Using menu templates


Delete Templates (Menu Designer SpeedMenu)
Delete Templates (Menu Designer SpeedMenu)1050017

See also

Choose Delete Templates from the Menu Designer SpeedMenu to open the Delete Templates dialog box.

Delete Templates dialog box

Use this dialog box to select and remove a predesigned menu.

Note:	After you delete a template, you cannot retrieve it.


See also1050018

Using menu templates


Insert from Resource (Menu Designer SpeedMenu)
Insert from Resource (Menu Designer SpeedMenu)1050019

See also

Choose Insert From Resource from the Menu Designer SpeedMenu to open the Insert Menu From Resource dialog box.

Insert Menu From Resource dialog box

Use this dialog box to import a menu from a Windows resource (.RC) file. You first need to save each individual menu as a separate resource file.

Dialog box options

File Name

Enter the name of the file you want to use, or enter wildcards to use as filters in the Files list box.

Files

Displays the files in the current directory that match the wildcards in the File Name edit box or the file type in the List Files Of Type combo box.

List Files Of Type

Choose the type of file you want to open; the default file type is a menu file (.MNU). All files in the current directory of the selected type appear in the Files list box.

Directories

Select the directory whose contents you want to view. In the current directory, files that match the wildcards in the File Name input box or the file type in the List Files of Type combo box appear in the Files list box.

Drives

Select the current drive. The directory structure for the current drive appears in the Directories list box.


See also1050020

Importing menus from resource files


Switching amoung menus at design time
Switching among menus at design time1050021

See also

If you are designing several menus for your form, you can use the Menu Designer SpeedMenu or the Object Inspector to easily select and move among them.

To use the SpeedMenu to switch among menus in a form,

1.	Right-click in the Menu Designer to display the SpeedMenu.

2.	From the SpeedMenu, choose Select Menu.

The Select Menu dialog box appears. This dialog box lists all the menus associated with the form whose menu is currently open in the Menu Designer.

3.	From the list in the Select Menu dialog box, choose the menu you want to view or edit.

To use the Object Inspector to switch among menus in a form,

1.	Give focus to the form whose menus you want to choose from.

2.	From the Component list, select the menu you want to edit.

3.	On the Properties page of the Object Inspector, select the Items property for this menu, and then either click the ellipsis button (...), or double-click [Menu].


See also1050022

Menu Designer SpeedMenu


Using menu templates
Using menu templates1050023

See also

Delphi provides several predesigned menus, or menu templates, that contain frequently used commands. You can use these menus in your applications without modifying them (except to write code), or you can use them as a starting point, customizing them as you would a menu you originally designed yourself. Menu templates do not contain any event handler code.

Menu templates are stored in the file DELPHI.DMT. The menu templates shipped with Delphi also reside in this file. In a default installation, this file is in the \DELPHI\BIN directory. If you want to store the DELPHI.DMT file in a different directory, add the following lines to your WINDOWS\DELPHI.INI file, replacing "directory" with a directory you choose:

[Globals]

PrivateDir=directory

You can also save as a template any menu that you design using the Menu Designer. After saving a menu as a template, you can use it as you would any predesigned menu. If you decide you no longer want a particular menu template, you can delete it from the list.

To add a menu template to your application,

1.	Right-click the Menu Designer window.

The Menu Designer SpeedMenu appears.

2.	From the SpeedMenu, choose Insert From Template.

(If there are no templates, the Insert From Template option appears dimmed in the SpeedMenu.)

The Insert Template dialog box opens, displaying a list of available menu templates.

3.	Select the menu template you want to insert, then press Enter or choose OK.

This inserts the menu into your form at the cursor's location. For example, if your cursor is on a menu item in a list, the menu template is inserted above the selected item. If your cursor is on the menu bar, the menu template is inserted to the left of the cursor.

To delete a menu template,

1.	Right-click the Menu Designer window.

The Menu Designer SpeedMenu appears.

2.	From the SpeedMenu, choose Delete Templates.

(If there are no templates, the Delete Templates option appears dimmed in the SpeedMenu.)

The Delete Templates dialog box opens, displaying a list of available templates.

3.	Select the menu template you want to delete, and press Del.

Delphi deletes the template from the templates list and from your hard disk.


See also1050024

Designing menus

Saving a menu as a template


Saving a menu as a template
Saving a menu as a template1050025

See also

Any menu you design can be saved as a template so you can use it again. You can use menu templates to provide a consistent look to your applications, or use them as a starting point which you then further customize.

The menu templates you save are stored in the DELPHI.DMT file in your \DELPHI\BIN directory.

You edit the template file by using the template commands from the Menu Designer SpeedMenu.

To save a menu as a template,

1.	Choose Save As Template from the Menu Designer SpeedMenu to open the Save Template dialog box.

2.	In the Template Description edit box, enter a brief description for this menu.

3.	Click OK.

The Save Template dialog box closes, saving your menu design and returning you to the Menu Designer window.

Note:	The description you enter is displayed only in the Save Template, Insert Template, and Delete Templates dialog boxes. It is not related to the Name or Caption property for the menu.

When you save a menu as a template, Delphi does not save its Name, since every menu must have a unique name within the scope of its owner (the form). However, when you insert the menu as a template into a new form by using the Menu Designer, Delphi then generates new names for it and all its items.

Delphi also does not save any event handlers associated with a menu saved as a template, since Delphi cannot test whether the code would be applicable in a new form. You can associate menu items in the template with existing event handlers in the form.


See also1050026

Associating menu events with code

Using menu templates


Importing menus from resource files
Importing menus from resource files1050027

See also

Delphi supports menus built with other applications, so long as they are in the standard Windows resource (.RC) file format. You can import such menus directly into your Delphi project, saving you the time and effort of rebuilding menus that you created elsewhere.

To load an existing .RC menu file,

1.	In the Menu Designer, place the cursor where you want the menu to appear.

The imported menu can be part of a menu you are designing, or an entire menu in itself.

2.	From the Menu Designer SpeedMenu, choose Insert From Resource.

The Insert Menu From Resource dialog box appears.

3.	In the dialog box, select the resource file you want to load,

4.	Choose OK.

Note:	If your resource file contains more than one menu, you first need to save each menu as a separate resource file before importing it.


See also1050028

Designing menus


Using the Object Repository
Using the Object Repository1044001

See also

Delphi's Object Repository provides a versatile mechanism for sharing forms, dialog boxes, and data modules across projects. It can also help with reusing similar forms in a single project, and provides project templates as starting points for new projects.

The following topics focuse on how to use the Object Repository in general as a project management tools and discusses some of the mechanics of using project templates.

About the Object Repository

Changing defaults for new projects

Customizing the Object Repository

Object Repository usage options

Using project templates

Using the Object Repository in a shared environment


Object RepositorySA
See also1044002

 Object Repository dialog box


About the Object Repository
About the Object Repository1044003

See also

Delphi provides the Object Repository as a means for sharing and reusing forms and projects. The repository itself is really just a text file that contains references to forms, projects, and experts. Details of the file format are in online Help. The Object Repository has replaced the Gallery in this version of Delphi.

Sharing across projects

By adding forms, dialog boxes, and data modules to the Object Repository, you make them available to other projects. For example, in a simple case, you could have all your projects use the same About box, copied from the Object Repository. A more advanced use of the Object Repository would be to have a standard empty dialog box with the company or product logo and standard button placement, from which all your projects derive standard-looking dialog boxes.

These sharing options are described in detail in Object Repository usage options.

Sharing within projects

The Object Repository can also help you to share items within a project, by allowing you to inherit from forms already in the project. When you open the New Items dialog box (by choosing File|New), you'll see a page tab with the name of your project. If you click that page tab, you'll see all the forms, dialog boxes, and data modules in your project. You can then derive a new item from the existing item, and customize it as needed.

For example, in a database application you might need several forms that display the same data, but which provide different command buttons. Instead of creating and maintaining several nearly-identical forms, you could lay out a generic form that contains all the data-display controls, then create separate forms that inherit the data-display layout, but have different command buttons.

By carefully planning your project forms, you can save tremendous amounts of time and effort by sharing forms within projects.

Sharing entire projects

You can also add an entire project to the Object Repository as a template for future projects. If you have a number of similar applications, for example, you can base them all on a single, standardized model.

Using experts

The Object Repository also contains references to experts, which are small applications that lead the user through a series of dialog boxes to create a form or project. Delphi provides a number of experts, and you can also add your own.


Object Repository usage options
Object Repository usage options1044004

See also

When you use an item from the Object Repository in a project you have as many as three options on how to include that item. Keep in mind that items in the Object Repository are there to be shared, and that you want to use them in ways that help, rather than hinder, reuse.

In general, you these are the three options for using Object Repository items:

Copy the item

Inherit from the item

Use the item directly

Copying items from the Object Repository

The simplest sharing option is to copy an item from the Object Repository into your project. Copying makes an exact duplicate of the item as it stands and adds the copy to your project. Future changes to the item in the Object Repository will not be reflected in your copy, and alterations made to your copy will not affect the original Object Repository item.

Note:	Copying is the only option available for using project templates.

Inherit from Object Repository items

The most flexible and powerful sharing option is to inherit from an item in the Object Repository. Inheriting derives a new class from the item and adds the new class to your project. When you recompile your project, any changes made to the item in the Object Repository will be reflected in your derived class, unless you have changed a particular aspect. Changes made to your derived class do not affect the shared item in the Object Repository.

Note:	Inheriting is available as an option for forms, dialog boxes, and data modules, but not for project templates. It is the only option available for reusing items from within the same project.

Using Object Repository items directly

The least flexible sharing option is using an item from the Object Repository directly in your project. Using the item adds the item itself to your project, just as if you had created it as part of that project. Design-time changes made to the item therefore appear in all projects that directly use the item, as well as affecting any projects that inherit from the item.

Note:	Using items directly is an available option for forms, dialog boxes, and data modules.

Items shared this way should generally be modified only at run time, to avoid making changes that affect other projects.

The Use option is the only option available for experts, whether form experts or project experts. Using an expert doesn't actually add shared code, but rather runs a process that generates its own code.


Using project templates
Using project templates1044005

See also

Delphi provides project templates, pre-designed projects you can use as starting points for your own projects. Project templates are part of the Object Repository (located in the OBJREPOS subdirectory), which also provides form objects and experts.

When you start a project from a project template (other than the blank project template), Delphi prompts you for a project directory, a subdirectory in which to store the new project's files. If you specify a directory that doesn't currently exist, Delphi creates it for you. Delphi copies the template files to the project directory. You can then modify it, adding new forms and units, or use it unmodified, adding only your event-handler code. In any case, your changes affect only the open project. The original project template is unaffected and can be used again.

To start a new project from a project template,

1.	Choose File|New to display the New Items dialog box.

2.	Choose the Projects tab.

3.	Select the project template you want and choose OK.

4.	In the Select Directory dialog box, specify a directory for the new project's files.

A copy of the project template opens in the specified directory.

Adding projects to the Object Repository

You can add your own projects and forms to those already available in the Object Repository. This is helpful in situations where you want to enforce a standard framework for programming projects throughout an organization.

For example, suppose you develop custom billing applications. You might have a generic billing application project that contains the forms and features common to all billing systems. Your business centers around adding and modifying features in this application to meet specific client requirements. In such a case, you might want to save the project containing your Generic Billing application as a project template and perhaps specify it as the default new project on your Delphi development system. Likewise, you'll probably have a particular form within this project that you want to appear as the default main or new form.

To add a project to the Object Repository,

1.	If necessary, open the project you want added to the Object Repository.

2.	Choose Tools|Repository.

3.	On the Project Templates page, choose Add to display the Save Project Template dialog box.

4.	In the Title edit box, enter a project title.

 The title for the template will appear in the Object Repository window.

5.	In the Description field, enter text that describes the template.

 This text will appear in the Object Repository window's status bar.

6.	In the Page field, choose the name of the page in the New Items dialog box (probably Projects) you want the template to appear on.

7.	In the Author field, enter text identifying the author of the application.

 Author information appears only when the user views the repository items with full details.

8.	Choose Browse to select an icon to represent this template in the Object Repository.

9.	Choose OK to save the current project as a project template.

Note:	If you later make changes to a project template, those changes automatically appear in new projects created from that template. They will not, however, affect projects already created from that template.

You can also save your own forms as form templates and add them to those already available in the Object Repository. This is helpful in situations where you want to develop standard forms for an organization's software, as in the earlier example.

To add a form to the Object Repository as a template, follow the preceding steps for adding projects as templates, using the Form Templates page of the Object Repository Options dialog box instead of the Project Templates page.


Customizing the Object Repository
Customizing the Object Repository1044006

See also

The settings in the Object Repository Options dialog box affect the behavior of Delphi when you begin a new project or create a new form in an open project. This is where you specify

Default project

Default new form

Default main form

You always have to option to override these defaults by choosing File|New and selecting from the New Items dialog box.

By default, opening a new project displays a blank form. You can change this default behavior by changing Object Repository options.

Specifying the default new project

The default new project opens whenever you choose New Application from the File menu on the Delphi menu bar. If you haven't specified a default project, Delphi creates a blank project with an empty form. You can specify a project template (including a project you have created and saved as a template) as the default new project.

You can also designate a project expert to run by default when you start a new project. A project expert is a program that enables you to build a project based on your responses to a series of dialog boxes.

To specify the default new project,

1.	Choose Tools|Repository to display the Object Repository dialog box.

2.	Choose Projects in the Pages list.

3.	Select the project object you want as the default new project from the Objects list.

4.	With the object you want selected, check New Project.

5.	Choose OK to register the new default setting.

Specifying the default new form

The default new form opens whenever you choose File|New Form or use the Project Manager to add a new form to an open project. If you haven't specified a default form, Delphi uses a blank form. You can specify any form template, including a form you have created and saved as a template, as the default new form. Or you can designate a form expert to run by default when a new form is added to a project.

To specify the default new form for new projects,

1.	Choose Tools|Repository to display the Object Repository dialog box.

2.	Choose Forms in the Pages list.

3.	Select the form object you want as the default new form.

4.	With the object you want selected, check New Form.

5.	Choose OK to register the new default setting.

Specifying the default main form

Just as you can specify a form template or expert to be used whenever a new form is added to a project, you can also specify a form template or expert that should be used as the default main form whenever you begin a new project.

To specify the default main form for open projects,

1.	Choose Tools|Repository to display the Object Repository dialog box.

2.	Choose Forms in the Pages list.

3.	Select the form object you want as the default main form.

4.	With the object you want selected, check Main Form.

5.	Choose OK to register the new default setting.


Changing defaults for new projects
Changing defaults for new projects1044007

See also

The Project Options dialog box contains a check box labeled Default. This control enables you to modify some of Delphi's default project configuration properties. Checking this control writes the current settings from the Compiler, Linker, and Directories/Conditionals pages of the Project Options dialog to a file called DEFPROJ.DOF. Delphi creates this file when you check the Default box and choose OK in the Project Options dialog box. Delphi then uses the project options settings stored in this file as the default for any new projects you create.

If you create a project from a template in the Object Repository that has its own options file, those settings will override the default settings in DEFPROJ.DOF.

To restore Delphi's original default settings, delete or rename the DEFPROJ.DOF file.

Note:	Project options you set for an open project override the current Delphi defaults, whether those defaults are as originally shipped or as modified by you or another user.


Using the Object Repository in a shared environment
Using the Object Repository in a shared environment1044008

To change the location where Delphi looks for the Object Repository File, DELPHI32.DRO, create a new String Value called "BaseDir" in the 滴KEY_CURRENT_USER | Software | Borland | Delphi | 2.0 | Repository� key in the Windows Registry Editor and set its Value data to the directory where this file is to be located.  It is recommended that the location uses the UNC name when the DELPHI32.DRO file is to be shared.

It is suggested that Forms and Projects be saved using UNC names when they will be added to a shared Repository.

While someone is modifying the Object Repository (DELPHI32.DRO file), anyone attempting to open or add to the repository will get a dialog box with the user name of the person that has the repository open.  If you are attempting to open the repository from Tools | Object Repository, the dialog box will ask if you wish to view the repository. If you choose to view the repository, you will not be allowed to save any changes.

Lock information is stored in the DELPHI32.DRL file. If this lock file cannot be opened, an exception is raised.  This can mean the file is read-only or the user doesn稚 have write rights for the directory.  Also, if someone exits from Delphi abnormally while modifying the repository, the lock file may still contain information that the user is editing the repository and you will not be allowed to modify the DELPHI32.DRO file. In this case the lock file should be deleted.


<Library Name>is already loaded, probably as a result of an incorrect program termination. Your system may be unstable and you should exit and restart Windows now.1011001

An error occurred while attempting to initialize Delphi's component library.  One or more DLLs are already in memory, probably as a result of an incorrect program termination in a previous Delphi or BDE session.

You should exit and then restart Windows.


<IDname> is not a valid identifier1011002

The identifier name is invalid. Ensure that the first character is a letter or an underscore (_). The characters that follow must be letters, digits, or underscores, and there cannot be any spaces in the identifier.


A field or method named <Name> already exists1011003

The name you have specified is already being used by an existing method or field.

For a complete list of all fields and methods defined, check the form declaration at the top of the unit source file.


A component class named <Name> already exists1011004

The component library already contains a component with the same class name you have specified.


Breakpoint is set on line that contains no code or debug information. Run anyway?1011005

A breakpoint is set on a line that does not generate code or in a module which is not part of the project.  If you choose to run anyway, invalid breakpoints will be disabled (ignored).


Could not stop due to hard mode1011006

The integrated debugger has detected that Windows is in a modal state and will not allow the debugger to stop your application.  Windows enters "hard mode" whenever processing an inter-task SendMessage, when there is no task queue, or when the menu system is active.  You will not generally encounter hard mode unless you are debugging DDE or OLE processes within Delphi.

A standalone debugger such as the Turbo Debugger for Windows can be used to debug applications even when Windows is in hard mode.


Another file named <FileName> is already on the search path1011007

A file with the same name as the one you just specified is already in another directory on the search path.


Cannot find <FileName.PAS> or <FileName.DCU> on the current search path1011008

The .PAS or .DCU file you just specified cannot be found on the search path.

You can modify the search path, copy the file to a directory along the path, or remove the file from the list of installed units.


Cannot find implementation of method <MethodName>1011009

The indicated method is declared in the form's class declaration but cannot be located in the implementation section of the unit.  It probably has been deleted, commented out, renamed, or incorrectly modified.

Use UNDO to reverse your changes, or correct the procedure declaration manually.  Be sure the declaration in the class is identical to the one in the implementation section.  (This is done automatically if you use the Object Inspector to create and rename event handlers.)

For more information about the syntax of procedure declarations, see Procedures and functions


Debug session in progress. Terminate?1011010

Your application is running and will be terminated if you proceed.  When possible, you should cancel this dialog and terminate your application normally (for example, by selecting Close on the System Menu).


Declaration of class <ClassName> is missing or incorrect1011011

Delphi is unable to locate the form's class declaration in the interface section of the unit.  This is probably because the type declaration containing the class has been deleted, commented out, or incorrectly modified.  This error will occur if Delphi cannot locate a class declaration equivalent to the following:

type

...

TForm1 = class(TForm)

...

Use UNDO to reverse your edits, or correct the declaration manually.  For more information about class declaration syntax, see Class Types.


Error address not found1011012

The address you have specified cannot be mapped to a source code position.  This error usually occurs for one of the following reasons:

The address you entered is invalid or is not an address in your application.

The module containing the specified address was not compiled with debug information.

The address specified does not correspond to a program statement.

Note that the runtime and visual component libraries are compiled without debug information.


Error creating process: <Process> (<ErrorCode>)1011013

Delphi was unable to start your application for the reason specified.

For more information about "Insufficient memory to run" errors, see README.TXT.


Field <Field Name> does not have a corresponding component. Remove the declaration?1011014

The first section of your form's class declaration defines a field for which there is no corresponding component on the form.  Note that this section is reserved for use by the form designer.

To declare your own fields and methods, place them in a separate public, private, or porotected section.

This error will also occur if you load the binary form file (.DFM) into the Code Editor and delete or rename one or more components.


Field <Field Name> should be of type <Type1> but is declared as <Type2>. Correct the declaration?1011015

The type of specified field does not match its corresponding component on the form.  This error will occur if you change the field declaration in the Code Editor or load the binary form file (.DFM) into the Code Editor and modify the type of a component.

If you select No and run your application, an error will occur when the form is loaded.


IMPLEMENTATION part is missing or incorrect1011016

In order to keep your form and source code synchronized, Delphi must be able to find the unit's implementation section.  This reserved word has been deleted, commented out, or misspelled.

Use UNDO to reverse your changes or correct the reserved word manually.  For more information about unit syntax, see Unit syntax.


Incorrect field declaration in class <ClassName>1011017

In order to keep your form and source code synchronized, Delphi must be able to find and maintain the declaration of each field in the first section of the form's class definition.  Though the compiler allows more complex syntax, the form designer will report an error unless each field that is declared in this section is equivalent to the following:

type

...

TForm1 = class(TForm)

Field1:FieldType;

Field2:FieldType;

...

This error has occurred because one or more declarations in this section have been deleted, commented out, or incorrectly modified.  Use UNDO to reverse your changes or correct the declaration manually.

Note that this first section of the form's class declaration is reserved for use by the form designer.  To declare your own fields and methods, place them in a separate public, private, or protected section.


Incorrect method declaration in class <ClassName>1011018

In order to keep your form and source code synchronized, Delphi must be able to find and maintain the declaration of each method in the first section of the form's class definition.  The form designer will report an error unless the field and method declarations in this section are equivalent to the following:

type

...

TForm1 = class(TForm)

Field1:FieldType;

Field2:FieldType;

...

<Method1 Declaration>;

<Method2 Declaration>;

...

...

This error has occurred because one or more method declarations in this section have been deleted, commented out, or incorrectly modified.  Use UNDO to reserve your changes or correct the declaration manually.

Note that this first section of the form's class declaration is reserved for use by the form designer.  To declare your own fields and methods, place them in a separate public, private, or protected section.


Insufficient memory to run1011019

Delphi was unable to run your application due to insufficient memory or Windows resources.  Close other Windows applications and try again.

This error sometimes occurs because of insufficient low (conventional) memory.  For further information, see README.TXT.


Invalid event profile <Name>1011020

The VBX control you are installing is invalid.


Module header is missing or incorrect1011021

The module header has been deleted, commented out, or otherwise incorrectly modified.  Use UNDO to reverse your changes, or correct the declaration manually.

In order to keep your form and source code synchronized, Delphi must be able to find a valid module header at the beginning of the source file.  A valid module header consists of the reserved word unit, program or library, followed by an identifier (for example, Unit1, Project1), followed by a semi-colon.  The file name must match the identifier.

For example, Delphi will look for a unit named Unit1 in UNIT1.PAS, a project named Project1 in PROJECT1.DPR, and a library (.DLL) named MyDLL in MYDLL.DPR.

Note that module identifiers cannot exceed eight characters in length.


No code was generated for the current line1011022

You are attempting to run to the cursor position, but you have specified a line that did not generate code, or is in a module which is not part of the project.

Specify another line and try again.

Note that the smart linker will remove procedures that are declared but not called by the program (unless they are virtual method of an object that is linked in).


Property and method <MethodName> are not compatible1011023

You are assigning a method to an event property even though they have incompatible parameter lists.  Parameter lists are incompatible if the number of types of parameters are not identical.  For a list of compatible methods in this form, see the dropdown list on the Object Inspector Events page.


Source has been modified. Rebuild?1011024

You have made changes to one or more source or form modules while your application is running.  When possible, you should terminate your application normally (select No, switch to your running application, and select Close on the System Menu), and then run or compile again.

If you select Yes, your application will be terminated and then recompiled.


Symbol <BrowseSymbol> not found. 1011025

The browser cannot find the specified symbol.  This error will occur if you enter an invalid symbol name or if debug information is not available for the module that contains the specified symbol.


The <Method Name> method referenced by <Form Name> does not exist. Remove the reference?1011026

The indicated method is no longer present in the class declaration of the form.  This error occurs when you manually delete or rename a method in the form's class declaration that is assigned to an event property.

If you select No and run this application, an error will occur when the form is loaded.


The <Method Name> method referenced by <Form Name>.<Event Name> has an incompatible parameter list. Remove the reference?1011027

A form has been loaded that contains an event property mapped to a method with an incompatible parameter list.  Parameter lists are incompatible if the number or types of parameters are not identical.

For a list of methods declared in this form which are compatible for this event property, use the dropdown list on the Object Inspector's Events page.

This error occurs when hyou manually modify a method declaration that is referenced by an event property.

Note that it is unsafe to run this program without removing the reference or correcting the error.


The project already contains a form or module named <Name>1011028

Every module name (program or library, form and unit) in a project must be unique.


USES clause is missing or incorrect1011029

In order to keep your forms and source code synchronized, Delphi must be able to find and maintain the USES clause of each module.

In a unit, a valid USES clause must be present immediately following the interface reserved word.  In a program or library, a valid USES clause must be present immediately following the program or library header.

This error occurs because the USES clause has been deleted, commented out, or incorrectly modified.  Use UNDO to reverse your changes or correct thte declaration manually.  For more information about the USES clause syntax, see the reserved word USES.


テーブル検索
テーブル検索1004001

特定のレコードを見つけるためのテーブル検索には，一般的な検索メソッドの Locate と Lookup が使えます。この 2 つのメソッドは，列にインデックスが付いているかキーが付いているかに関係なく，任意のテーブルのどの列を対象にしても検索が行えます。

また，前バージョンの Delphi との互換性のために，テーブルコンポーネントは Goto メソッドと Find メソッドを引き続きサポートしています。この 2 つのメソッドはこれまでのアプリケーションでの操作を可能にするためにここに示しましたが，新しいアプリケーションでは必ず Locate と Lookup を使ってください。さらに，既存のアプリケーションを新しいメソッドを使うように書きかえることで，処理効率がよくなる可能性があります。

Locate の使い方

Locate メソッドは指定された検索条件に一致する最初の行にカーソルを移動します。もっとも簡単な形式では，検索する列の名前，照合する項目値，オプションフラグ（大文字小文字を区別しない検索か，部分キー照合を使えるかの指定）を Locate に渡します。たとえば次のコードは，Company 列の値が「Professional Divers，Ltd.」であるような CustTable の最初の行にカーソルを移動します。

var

  LocateSuccess: Boolean;

  SearchOptions: TLocateOptions;

begin

  SearchOptions := [loPartialKey];

  LocateSuccess := CustTable.Locate('Company', 'Professional Divers, Ltd.',
    SearchOptions);

end;

一致するレコードが見つかった場合，Locate は True を返します。見つからなかった場合，Locate は False を返します。検索に成功した場合，一致した最初のレコードが現在のレコードになります。失敗した場合，現在のレコードは変わりません。

Locate の本当の威力が発揮されるのは，複数の列で複数の値を指定して検索する場合です。検索値はバリアントで，検索条件にいろいろなデータ型を指定できるようになっています。検索文字列に複数の列を指定するには，その文字列の各項目をセミコロンで区切ります。

検索値はバリアントなので，複数の値を渡す場合は，バリアント配列型を引数として渡すか（たとえば，Lookup メソッドからの戻り値），VarArrayOf 関数を使ってバリアント配列をその場で作成する必要があります。次のコードは，複数の検索値と部分キー照合を使って複数の列で検索するコードの例です。

with CustTable do

  Locate('Company;Contact;Phone', VarArrayOf(['Sight Diver','P']), loPartialKey);

Locate は一番速い方法でレコードを検索します。検索する列にインデックスが付いており，そのインデックスが指定の検索オプションと互換性があれば，Locate はそのインデックスを使います。そうでなければ，検索用に BDE フィルタが作成されます。

Lookup の使い方

Lookup メソッドは指定された検索条件に一致する最初の行を探します。一致する行が見つかると，そのデータセットに関連した計算項目と参照項目が必ず再計算され，一致した行から 1 つまたは複数の項目が返されます。Lookup では一致した行にカーソルが移動することはなく，その行から値が返されるだけです。

もっとも簡単な形式では，検索する列の名前，照合する項目値，返す 1 つまたは複数の項目を Lookup に渡します。たとえば次のコードは，Company 列の値が「Professional Divers，Ltd」であるような CustTable の最初の行を探し，会社名，担当者，会社の電話番号を返します。

var

  LookupResults: Variant;

begin

with CustTable do

  LookupResults := Lookup('Company', 'Professional Divers, Ltd.', 'Company;
    Contact; Phone');

end;

Lookup メソッドは，最初に見つかった一致するレコードから指定項目の値を返します。値はバリアントとして返されます。複数の戻り値を要求した場合，Lookup はバリアント配列を返します。一致するレコードがない場合，Lookup はヌルのバリアントを返します。バリアント配列についての詳細は，『Object Pascal 言語リファレンス』を参照してください。

Lookup の本当の威力が発揮されるのは，複数の列で複数の値を指定して検索する場合です。複数の列や結果項目を持つ文字列を指定するには，その文字列の各項目をセミコロンで区切ります。

検索値はバリアントなので，複数の値を渡す場合は，バリアント配列型を引数として渡すか（たとえば，Lookup メソッドからの戻り値），VarArrayOf 関数を使ってバリアント配列をその場で作成する必要があります。次のコードは，複数の列で Lookup の検索をするコードの例です。

var

  LookupResults: Variant;

begin

with CustTable do

  LookupResults := Lookup('Company; City', VarArrayOf(['Sight Diver', 'Christiansted']),
    'Company; Addr1; Addr2; State; Zip');

end;

Lookup は一番速い方法でレコードを検索します。検索する列にインデックスが付いていれば，Lookup はそのインデックスを使います。そうでなければ，検索用に BDE フィルタが作成されます。


トランザクション処理
トランザクション処理1006001

暗黙の制御や明示的な制御を使って Delphi データベースアプリケーション内でトランザクションを処理する方法は 2 種類あります。特に以下の 2 つが中心です。

明示的にトランザクションを制御できる TDatabase コンポーネントのメソッドとプロパティの使い方

トランザクションを制御する TQuery コンポーネントのパススルー SQL の使い方

また，Delphi はローカルトランザクション，つまりローカルの Paradox テーブルや dBASE テーブルに対して実行されるトランザクションもサポートしています。

トランザクションについて

Delphi を使ってデータベースアプリケーションを作成する場合，ローカルの Paradox テーブルや dBASE テーブルも含め，すべてのデータベースアクセスについてトランザクションを制御できます。トランザクションはアクションのグループであり，そのすべてのアクションは，コミット（確定）される前にデータベース内の 1 つまたは複数のテーブルに対して正常に実行されなければなりません。グループ内のアクションが 1 つでも失敗すると，すべてのアクションが失敗します。

ハードウェア障害があっても，トランザクションによってデータベースの一貫性が保証されます。マルチユーザーの同時アクセスを許しながら，データの整合性も保ちます。

たとえば，ある商品の注文を受けたことを示すためにアプリケーションで ORDERS テーブルを更新し，次に在庫の減少を示すために INVENTORY テーブルを更新する場合を考えます。ORDERS テーブルを更新した後で INVENTORY テーブルを更新する前にハードウェア障害があると，受けた注文が在庫に反映されず，データベースは一貫性を失います。トランザクション制御の下では，両方の文が同時にコミットされます。一方の文が失敗した場合，両方とも取り消され（ロールバックされ）ます。

暗黙のトランザクション制御

デフォルトでは，Borland Database Engine（BDE）を通じて暗黙のトランザクション制御がアプリケーションに提供されます。アプリケーションが暗黙のトランザクション制御の下にある場合，基になったデータベースに書き込まれるデータセットのレコードごとに別々のトランザクションが使われます。Post や AppendRecord などの書き込み処理は，個別にコミットされます。

暗黙のトランザクション制御を使用するとレコード更新の衝突が最小限になり，データベースのビューの一貫性が保証されます。しかし，データベースへの各データ行の書き込みがそれぞれのトランザクション内で行われるため，ネットワークトラフィックが過大になったり，アプリケーションの処理効率が低下することがあります。

明示的なトランザクション制御では，トランザクションを開始，コミット，ロールバックするのにもっとも効果的なタイミングを選択できます。マルチユーザー環境でのクライアントアプリケーションを開発する場合，Sybase，Oracle，Microsoft SQL，InterBase などのリモート SQL サーバーや，Access，FoxPro といった ODBC 準拠のリモートデータベースに対して実行するアプリケーションでは特に，トランザクションを明示的に制御する必要があります。

メモ:	キャッシュアップデートを使うと，アプリケーション内で使わなければならないトランザクションの数を最小限にできる場合があります。キャッシュアップデートについての詳細は，『データベースアプリケーション開発者ガイド』の第 15 章「キャッシュアップデートの操作」を参照してください。

明示的なトランザクション制御の操作

Delphi データベースアプリケーションでは，以下の 2 つのどちらかの方法でトランザクションを明示的に制御できます。

TDatabase コンポーネントのメソッドとプロパティを使う

TQuery コンポーネントのパススルー SQL を使う。パススルー SQL は Delphi Client/Server Suite でしか意味を持たない。Delphi Client/Server Suite では，SQL Link を使ってリモートの SQL サーバーまたは ODBC サーバーに SQL 文を直接渡す

トランザクション制御にデータベースコンポーネントのメソッドとプロパティを使う一番の利点は，特定のデータベースまたはサーバーに依存しない，簡潔で移植性のあるアプリケーションを作成できることです。

パススルー SQL を使う一番の利点は，スキーマキャッシングなど，特定のデータベースサーバーの高度なトランザクション管理機能を使えることです。サーバーのトランザクション管理モデルの利点については，各データベースサーバーのマニュアルを参照してください。

TDatabase のメソッドとプロパティの使い方

次の表に TDatabase のトランザクション管理固有のメソッドとプロパティおよびその用途を示します。

メソッドまたはプロパティ	用途
Commit	データの変更をコミットし，トランザクションを終了する
Rollback	データの変更を元に戻し，トランザクションを終了する
StartTransaction	トランザクションを開始する
TransIsolation	トランザクションのアイソレーションレベルを指定する
StartTransaction，Commit，Rollback の各メソッドは実行時にアプリケーションから呼び出して，トランザクションの開始，トランザクション期間の制御，データベースの変更の保存または破棄に使えます。

TransIsolation プロパティは，複数のトランザクションが同一のテーブルを同時に操作するときのトランザクションどうしの対話を制御します。特に，ほかのトランザクションによるテーブルの変更の認識に影響します。

トランザクションを開始する

トランザクションを開始すると，その後でデータベースを読み書きするすべての文は，そのトランザクションのコンテキストで実行されます。それぞれの文はグループの一部とみなされます。グループ内のいずれかの文が書き込んだ変更が，データベースに正常にコミットされなければ，グループ内のすべての書き込み文が加えた変更は，すべて元に戻されます。

文のグループ化は，文がほかの文に依存する場合に便利です。現金自動預け払い機（ATM）での銀行取り引きについて考えてみます。普通預金口座から当座預金口座に預金を移す場合，銀行のデータベースレコードに以下の 2 つの変更が必要です。

普通預金口座への借方の記入

当座預金口座への貸方の記入

なんらかの理由で一方のアクションを完了できない場合，どちらのアクションも発生してはいけません。2 つのアクションは密接に関連しているので，単一のトランザクションで発生しなければなりません。

Delphi アプリケーションでトランザクションを開始するには，データベースコンポーネントの StartTransaction メソッドを呼び出します。

DatabaseInterBase.StartTransaction;

これ以降のすべてのデータベースアクションは，Commit または Rollback を次に呼び出してトランザクションを明示的に終了するまで，新しく開始したトランザクションのコンテキストで発生します。

トランザクションは必要最小限にすることが理想です。トランザクションがアクティブな時間が長くなるほど，そのデータベースに同時にアクセスするユーザーが増え，トランザクションの存続期間中に並行して開始，終了する同時トランザクションが多くなり，変更をコミットしようとするときに別のトランザクションと衝突する可能性が高くなります。

トランザクションをコミットする

データベースの変更を確定するには，データベースコンポーネントの Commit メソッドを使ってトランザクションをコミットしなければなりません。コミット文を実行すると，データベースの変更が保存され，トランザクションが終了します。たとえば，次の文は前述のコード例で開始したトランザクションを終了します。

DatabaseInterBase.Commit;

メモ:	Commit は必ず try...except 文の中で使うようにしてください。トランザクションを正常にコミットできない場合は，エラー処理を試行し，さらに操作を再試行できます。

トランザクションをロールバックする

データベースの変更を破棄するには，Rollback を使ってトランザクションはデータベースの変更をロールバックしなければなりません。Rollback はトランザクションによる変更を元に戻し，トランザクションを終了します。たとえば，次の文はトランザクションをロールバックします。

DatabaseInterBase.Rollback;

通常，Rollback は以下の 2 種類のコードの中で使います。

例外処理コード（データベースのエラーを回復できないとき）

ボタンまたはメニューのイベントコード（ユーザーが［キャンセル］ボタンをクリックした場合など）

TransIsolation プロパティ

TransIsolation は，データベースコンポーネントのトランザクションのアイソレーションレベルの指定に使います。トランザクションアイソレーションレベルは，同一のテーブルを操作する同時トランザクション間の対話方式を指定するものです。特に，ほかのトランザクションによるテーブルの変更の認識に影響します。TransIsolation を変更または設定する前に，Delphi のトランザクションとトランザクション管理についての知識が必要です。

TransIsolation のデフォルト設定は，tiReadCommitted です。表 4.2 に TransIsolation の値とその意味を示します。

アイソレーションレベル	意味
tiDirtyRead	ほかの同時トランザクションによってデータベースに加えられた，コミット（確定）されていない変更の読み取りを許す。コミットされていない変更は，いつでもロールバックできる（元に戻せる）。これはもっとも低いアイソレーションレベルである
tiReadCommitted	ほかの同時トランザクションによってコミット（確定）されたデータベースの変更だけ読み出せるようにする。これがデフォルトのアイソレーションレベルである
tiRepeatableRead	データベースの読み取りを単一回だけ許す。以後，ほかの同時トランザクションによるデータの変更をトランザクションは認識できない。このアイソレーションレベルでは，トランザクションがいったんレコードを読み出すと，そのレコードのビューが変化しないことが保証される。これはもっとも高いアイソレーションレベルである
データベースサーバーによっては，アイソレーションレベルのサポートが異なる場合や，まったくサポートされない場合があります。要求したアイソレーションレベルをサーバーがサポートしていない場合，次に高いアイソレーションレベルが使われます。次の表に各種のサーバーで実際に使われているアイソレーションレベルを示します。各アイソレーションレベルの実装状況についての詳細は，各サーバーのマニュアルを参照してください。

TransIsolation の設定	Paradox と dBASE	Oracle	Sybase サーバーと Microsoft SQL サーバー	InterBase
ダーティー読み取り	ダーティー読み取り	読み取りコミット	読み取りコミット	読み取りコミット
読み取りコミット (デフォルト)	未サポート	読み取りコミット	読み取りコミット	読み取りコミット
反復読み取り	未サポート	反復読み取り (読み取り専用)	未サポート	反復読み取り
メモ:	ローカル Paradox および dBASE テーブルでトランザクションを使う場合，TransIsolation をデフォルト値の tiReadCommitted ではなく tiDirtyRead に設定してください。ローカルテーブルに対して TransIsolation が tiDirtyRead 以外に設定されていると，BDE エラーが返されます。

アプリケーションが ODBC を使ってサーバーとのインターフェースを取る場合，ODBC ドライバもアイソレーションレベルをサポートしている必要があります。詳細については ODBC ドライバのマニュアルを参照してください。

パススルー SQL の使い方

トランザクションを制御するためにパススルー SQL を使うには，以下のことが必要です。

Delphi Client/Server Suite を使う

適切な SQL Link ドライバをインストールする。デフォルトインストールを選択して Delphi をインストールした場合，すべての SQL Link ドライバがすでに正しくインストールされている

ネットワークプロトコルを正しく設定する。詳細はネットワーク管理者に問い合わせる

リモートサーバーのデータベースにアクセスできる

BDE 環境設定ユーティリティを使って SQLPASSTHRU MODE を NOT SHARED に設定する

パススルー SQL を使ってリモートデータベースサーバーに SQL トランザクション制御文を直接送信するには，TQuery，TStoredProc，TUpdateSQL のいずれかのコンポーネントを使います。BDE は SQL 文を処理しません。パススルー SQL を使うと，サーバーのトランザクション制御が標準でない場合は特に，それらのトランザクション制御の利点を直接利用できます。

SQLPASSTHRU MODE を設定する

SQLPASSTHRU MODE には，BDE とパススルー SQL 文が同一のデータベース接続を共有できるかどうかを指定します。ほとんどの場合，SQLPASSTHRU MODE は SHARED AUTOCOMMIT に設定されます。ただし，SQL トランザクション制御文をサーバーに渡したい場合は，BDE 環境設定ユーティリティを使って SQLPASSTHRU MODE を NOT SHARED に設定しなければなりません。SQLPASSTHRU MODE についての詳細は，BDE 環境設定ユーティリティのオンラインヘルプを参照してください。

メモ:	SQLPASSTHRU MODE が NOT SHARED の場合，SQL 制御文をサーバーに渡す TQuery コンポーネントと，渡さないその他のデータセットコンポーネントに，それぞれ別のデータベースコンポーネントを使わなければなりません。

ローカルトランザクションの使い方

BDE は Paradox テーブルや dBASE テーブルに対するローカルトランザクションをサポートしています。コーディングの面では，ローカルトランザクションでもリモートデータベースサーバーにあるトランザクションでも違いはありません。

ローカルテーブルに対してトランザクションを開始すると，そのテーブルに対して実行された更新がログに記録されます。ログの各レコードには，レコードの以前のレコードバッファが記録されます。トランザクションがアクティブな場合，更新されるレコードは，そのトランザクションがコミットされるかロールバックされるまでロックされます。ロールバック時には，更新したレコードに対して以前のレコードバッファが使われ，レコードが更新前の状態に復元されます。

ローカルトランザクションの制限について

ローカルトランザクションには以下の制限があります。

クラッシュの自動復元はない

データ定義文はサポートされていない

Paradox の場合，ローカルトランザクションを実行できるのは，有効なインデックスがあるテーブルに対してだけである。インデックスがない Paradox テーブルでは，データをロールバックできない

一時テーブルに対してはトランザクションを実行できない

BDE ASCII ドライバに対してはトランザクションを実行できない

トランザクション中にテーブル上でカーソルを閉じると，以下の場合を除いて，トランザクションはロールバックされる

複数のテーブルを開いているとき

変更しなかったテーブル上でカーソルを閉じるとき


データソースの指定
データソースの指定1006002

TDataSource コンポーネントは，データセットとフォーム上のデータベース対応コンポーネントを仲介する非ビジュアルデータベースコンポーネントです。データベース対応コンポーネントは，データセットの基になるデータの表示，操作，編集を可能にします。フォーム上のデータベース対応コントロールにデータの表示や処理を行うには，すべてのデータセットをデータソースコンポーネントに関連付けなければなりません。同様に，データを表示したり処理するには，データベース対応コントロールもそれぞれデータソースコンポーネントに関連付ける必要があります。また，データセットをマスター／リンク関係でリンクするのにもデータソースコンポーネントが使えます。

ほかの非ビジュアルデータベースコンポーネントを追加するのと同じように，データソースコンポーネントもデータモジュールやフォームに追加できます。データモジュールやフォームの各データセットコンポーネントについて最低 1 つのデータソースコンポーネントを追加する必要があります。

TDataSource のプロパティの使い方

TDataSource のプロパティは数種類しかありません。以降の各節で，主要なプロパティの内容と，設計時および実行時にそれらのプロパティを設定する方法について説明します。

DataSet プロパティ

DataSet プロパティは，データソースコンポーネントのデータの取得元になるデータセットの名前を指定するのに使います。設計時にオブジェクトインスペクタのドロップダウンリストからデータセットを選択できます。実行時には，必要であればデータソースコンポーネント用のデータセットを切り替えられます。たとえば次のコードは，CustSource データソースコンポーネント用のデータセットを Customers と Orders の間で切り替えます。

with CustSource do

begin

  if DataSet = 'Customers' then

    DataSet := 'Orders'

  else

    DataSet := 'Customers';

end;

DataSet プロパティを別のフォーム上のデータセットに対して設定し，2 つのフォーム上のデータコントロールの同期をとることもできます。次に例を示します。

procedure TForm2.FormCreate (Sender : TObject);

begin

  DataSource1.Dataset := Form1.Table1;

end;

Name プロパティ

Name プロパティは，アプリケーションのほかのすべてのデータソースと区別できるようにデータソースコンポーネントに意味のある名前を指定するのに使います。データソースコンポーネントに付けた名前はデータモジュールのコンポーネントアイコンの下に表示されます。

一般にデータソースコンポーネントには，関連するデータセットを示す名前を付ける必要があります。たとえば Customers というデータセットがあるとします。そのデータセットにデータソースコンポーネントをリンクするには，データソースコンポーネントの DataSet プロパティに「Customers」を設定します。このデータセットとデータソースの接続を明確にするには，データソースコンポーネントの Name プロパティに「CustomersSource」などを設定する必要があります。

Enabled プロパティ

Enabled プロパティはデータソースコンポーネントがそのデータセットに接続されているかどうかを決めます。Enabled プロパティが True の場合，そのデータソースはデータセットに接続されています。

Enabled プロパティを False に設定すれば，単一のデータソースを一時的にデータセットから切断できます。Enabled が False の場合，データソースコンポーネントに結び付いたすべてのデータコントロールは空白になり，Enabled が True になるまで非アクティブになります。ただし，データセットコンポーネントの DisableControls メソッドおよび EnableControls メソッドを使ってデータセットへのアクセスを制御することをお勧めします。これらのメソッドは結び付けられたすべてのデータソースに影響を及ぼすからです。

AutoEdit プロパティ

TDataSource の AutoEdit プロパティは，データセットにリンクしたデータベース対応コントロールにユーザーが入力を開始したときに，データソースに接続されたデータセットが自動的に編集状態になるかどうかを指定します。AutoEdit が True（デフォルト）の場合，リンクされたデータベース対応コントロールにユーザーが入力するとデータセットは自動的に編集状態になります。それ以外の場合は，アプリケーションが明示的に Edit メソッドを呼び出したときにだけデータセットは編集状態になります。

TDataSource のイベントの使い方

TDataSource のイベントには関連する 3 つのイベントハンドラがあります。

OnDataChange

OnStateChange

OnUpdateData

OnDataChange イベント

OnDataChange イベントは，カーソルが新規レコードに移るたびに呼び出されます。アプリケーションが Next，Previous，Insert やカーソル位置を変えるその他のメソッドを呼び出すと，OnDataChange イベントが発生します。

このイベントは，アプリケーションがコンポーネントの同期を手動で保持している場合に使います。

OnUpdateData イベント

OnUpdateData イベントは，現在のレコードのデータを更新する際に呼び出されます。たとえば OnUpdateData イベントが発生するのは，Postが呼び出された後で，データが実際にデータベースに登録される前です。

このイベントは，アプリケーションが標準の（データベース対応でない）コントロールを使っているためにデータセットとの間で同期を保持する必要がある場合に使います。

OnStateChange イベント

OnStateChange イベントは，データソースのデータセットの状態が変わるたびに呼び出されます。データセットの State プロパティは現在の状態を記録しています。OnStateChange イベントは，TDataSource の状態が変化したときに操作する場合に使います。

たとえば，通常のデータベースセッションの進行中はデータセットの状態が頻繁に変化します。この変化を追跡するには，フォーム上のラベルに現在のデータセットの状態を表示するイベントハンドラ OnStateChange を記述します。次のコードはそうしたルーチンの記述例です。このコードは実行時に，データセットの State プロパティの現在の設定を表示し，設定が変わるたびに更新します。

procedure TForm1.DataSource1.StateChange(Sender:TObject);

var

  S:String;

begin

  case CustTable.State of

    dsInactive: S := 'Inactive';

    dsBrowse: S := 'Browse';

    dsEdit: S := 'Edit';

    dsInsert: S := 'Insert';

    dsSetKey: S := 'SetKey';

  end;

  CustTableStateLabel.Caption := S;

end;

同様に，現在の状態に基づいてボタンやメニュー項目の使用可能と使用不可を切り替える場合にも OnStateChange が使えます。

procedure Form1.DataSource1.StateChange(Sender: TObject);

begin

  CustTableEditBtn.Enabled := (CustTable.State = dsBrowse);

  CustTableCancelBtn.Enabled := CustTable.State in [dsInsert, dsEdit, dsSetKey];

  ...

end;


項目コンポーネントのデータディクショナリ属性集合の作成
項目コンポーネントのデータディクショナリ属性セットの作成1006003

データセット内でアプリケーションが使っているいくつかの項目が，Alignment，DisplayWidth，DisplayFormat，EditFormat，MaxValue，MinValue などの形式プロパティを共有する場合，まず単一の項目に対してそれらのプロパティを設定し，それからプロパティを属性セットとしてデータディクショナリに保存すると使いやすくなります。データディクショナリに保存された属性セットはほかの項目に簡単に適用できます。

データセットの項目コンポーネントに基づいて属性セットを作成する手順

1.	データセットをダブルクリックして項目エディタを呼び出します。

2.	プロパティの設定対象になる項目を選択します。

3.	オブジェクトインスペクタで項目の希望のプロパティを設定します。

4.	項目エディタのリストボックスを右クリックしてスピードメニューを呼び出します。

5.	［属性の上書き保存(S)］を選択して現在の項目のプロパティ設定を属性セットとしてデータディクショナリに保存します。

属性セットの名前のデフォルトは現在の項目の名前です。別の名前を指定するには，スピードメニューの［属性の上書き保存(S)］ではなく，［属性に名前を付けて保存(E)］を選択してください。

メモ:	データベースエクスプローラから属性セットを直接作成することもできます。データディクショナリから属性セットを作成した場合，その属性セットはどの項目にも適用されません。ただし，その属性セットに 2 つの追加属性を指定できます。1 つは TFloatField や TStringField などの項目型で，もう 1 つは属性セットに基づく項目がフォーム上にドラッグされたときに自動的にフォーム上に追加される TDBEdit や TDBCheckBox などのデータベース対応コントロールです。


データディクショナリの属性セットと項目コンポーネントの関連付け
データディクショナリの属性セットと項目コンポーネントの関連付け1006004

データセットでアプリケーションが使っている数個の項目が，Alignment，DisplayWidth，DisplayFormat，EditFormat，MaxValue，MinValue などの形式プロパティを共有しており，それらのプロパティ設定を属性セットとしてデータディクショナリに保存した場合，各項目の設定を手作業でやり直さなくても，簡単にその属性セットを項目に適用できます。さらに，データディクショナリの属性の設定を後で変更した場合，次に項目コンポーネントがデータセットに追加されたときにその変更は属性セットに関連するすべての項目に対して自動的に適用されます。

属性セットを項目コンポーネントに適用する手順

1.	データセットをダブルクリックして項目エディタを呼び出します。

2.	属性セットの適用対象となる項目を選択します。

3.	項目エディタのリストボックスを右クリックしてスピードメニューを呼び出します。

4.	［属性の関連付け(O)］を選択します。

5.	［属性の関連付け］ダイアログボックスを使って，適用する属性セットを選択するか入力します。データディクショナリに現在の項目と同じ名前の属性セットがある場合，その集合の名前が編集ボックスに表示されます。


データディクショナリの属性セットと項目コンポーネントの関連付け解除
データディクショナリの属性セットと項目コンポーネントの関連付け解除1006005

属性セットと項目コンポーネントの関連付けを中止したい場合は，次のようにして属性セットを項目コンポーネントから簡単に削除できます。

1.	データセットをダブルクリックして項目エディタを呼び出します。

2.	属性セットを削除する対象の項目を選択します

3.	項目エディタのリストボックスを右クリックしてスピードメニューを呼び出します。

4.	［属性の関連付けを取り消す(U)］を選択します。

項目コンポーネントから属性セットを削除した後，オブジェクトインスペクタを使ってそのプロパティを設定することや，別の属性セットをそのコンポーネントに関連付けることもできます。


What's new in Delphi 30
What�s new in Delphi 31052001

Delphi 3 offers the following new features and enhancements:

Package support

Code insight

Component templates

New documentation design

Visual Component Library enhancements

Run Time Library enhancements

Compiler changes

Multibyte character support

New Borland Database Engine (BDE) and SQL Links

Distributed datasets (Client/Server only)

COM support and ActiveX creation (Professional and Client/Server only)

Internet and Intranet development (Client/Server only)

OLEnterprise with Business Object Broker (Client/Server only)

New demo applications

Miscellaneous IDE enhancements


Package support
Package support1052002

Packages are special dynamic-link libraries used by Delphi applications, the Delphi IDE, or both. They allow code-sharing among applications, reducing executable size and conserving system resources. The Component Library has been re-engineered to take advantage of package technology. A specific package can be compiled without rebuilding the entire Library, and packages can be loaded on a per-project basis (so that only the packages used by the current project need to be loaded). All Delphi components are now installed in the IDE as packages. Packages can provide a solution for development of efficient application executables that need to be quickly and easily distributed.

The IDE has been enhanced in several ways to accommodate packages. A Package Editor and associated dialogs, including a package-creation expert, have been added. The Palette options page (accessed by selecting Component | Configure Palette, or by selecting Tools | Options and clicking the Palette tab) now displays the package where each component resides.

Using Packages


Code Insight
Code Insight1052003

Delphi's Code Insight enhancements display context-sensitive pop-up windows within the Code editor. Code Insight provides templates, code completion, method parameter lists, and tool-tip expression evaluation. These features are updated dynamically as you work in the IDE. To configure Code Insight, choose Tools | Environment Options and select the Code Insight tab.

Code templates

Code templates are common programming statement that you can quickly  insert into your code. Templates are available for common Pascal syntactic structures such as "if ... then ..." and "while" statements and "try ... except" blocks.

To access code templates in the editor, press <control>-j.

To add or edit templates, select the Code Insight tab in the  Environment Options dialog. Code templates are not multibyte-enabled.

Code completion

Code completiong is a quick way to select methods, properties, events, or arguments to enter into your code�

Type an object or class name followed by a period (.), to display a pop-up list of valid method, property, and event names.

Type an assignment statement and press <control>-<spacebar>, to display a pop-up a list of valid arguments for the variable.

Code parameters

When you type a method name followed by a left parenthesis, a pop-up window displays a list of required arguments with their syntax.

Tool-tip expression evaluation

While an application is stopped in debug mode, place the mouse cursor over any variable or property name in the Code editor. The value of the variable or property is shown in a pop-up window.  (This feature works best if compiler Optimization is turned off in the Project Options dialog.)

More code editor enhancements

Visual enhancements for debugger support have been added. The Code editor window now displays a gutter and gutter glyphs, which can be configured or turned off in the Environment | Options dialog (select Tools | Environment Options | Display).

IME (input method editor) support has been added for Asian-language environments. Comments and string values can now contain multibyte characters. Object Pascal identifiers (names of variables, constants, etc.) cannot use multibyte characters.

Text searches are supported across entire projects, across specified directories, and across all open files. To specify files for a search, choose Search | Find In Files, or choose Search | Find and click the Find In Files tab.


Component Templates
Component Templates1052004

Component templates are groups of components that you add to a form in a single operation. Templates allow you to configure components on one form, then save their arrangement and default properties on the Component palette for reuse on other forms.

Creating component templates


New documentation design
New documentation design1052005

The documentation set has been redesigned to better address your needs.

User�s Guide

Provides all the information you will need to use key features of the Delphi user interface and the basic fundamentals of creating applications using Object Pascal. All this information is duplicated in Help.

Developer�s Guide

This is the consolidation of two former books on database application development and component writing, plus additional topics in one volume.

Provides in-depth information on all the intermediate-to-advanced programming topics you will need to create database applications, custom components, and Internet and intranet applications. It describes how to work with COM and ActiveX. All this information is duplicated in Help.

Object Pascal Language Guide

Describes the syntax and semantics of the Object Pascal language, including the formal definition of the language. All this information is duplicated in Help.

Visual Component Library Reference

You will find the Visual Component Library Reference much easier to use. It provides information on visual components, those most commonly used. The information is organized by object with properties, methods, and events subordinated to their respective objects. This method allows you to easily understand in which object a property, method, or event originated.

Help provides information on all the available Delphi objects and components. Press F1 to display Help on any highlighted object and then navigate through the object and component hierarchy.


VCL enhancements
VCL enhancements1052006

The following components or component groups, objects, properties, methods, or events have been enhanced or are new to Delphi 3:

User interface design

Button and Tool Bar components (new)

Graphics enhancements

Input Method Editor (IME) Support (new)

TDatetimePicker (new)

TAnimate (new)

TPageControl, TTabControl

TSplitter (new)

TOpenPictureDialog and TSavePictureDialog (new)

IConFont, UpdateMEtricSettings, and CMSysFontChanged

Other components

Decision support components (new)

Chart components

QuickReport components

TThreadList (new)

COM/ActiveX

TOleContainer

TStaticText (new)

Database

DataSets

TClientDataSet (new)

DBRichEdit

DBCtrlGrid

TField

See Also

Internet and Intranet Development


TPageControl, TTabControl
TPageControl, TTabControl1052007

TPageControl and TTabControl have new properties: HotTrack, ScrollOpposite, and TabPosition.

HotTrack, if set to True, highlights the caption of each tab as the mouse pointer passes over it. ScrollOpposite moves previous rows of tabs to the other side of the control when a tab in a later row is selected. TabPosition determines whether the tabs are arranged at the top or the bottom of the control.

See Also

About PageControl

TPageControl

TTabControl


TSplitter
TSplitter1052008

A new visual component, TSplitter, appears on the Additional page of the Component palette. Splitters allow you to divide a form into arbitrary rectangular regions that can be resized by the user at run time.

See Also

About Splitter

Splitter


Chart Components
Chart Components1052009

A new group of visual components -- TChart, TDBChart, and TQRChart -- let you create custom graphs on a Delphi form.

See TChart


QuickReport Components
QuickReport Components1052010

The new QuickReport component set includes an Expert to create reports easily. Reports designed with QuickReport 1.0 are automatically converted at design time to version 2.0.


TDateTimePicker
TDateTimePicker1052011

A new visual component, TDateTimePicker, displays a list box for entering dates or times. Deployment of TDateTimePicker requires the latest version of COMCTL32.DLL (version 4.70, dated 8/9/96, approximately 370Kb). This file is available from Microsoft; if you've installed Internet Explorer 3.0 or MS Office 97, you already have it.

See DateTimePicker


TAnimate
TAnimate1052012

A new visual component, TAnimate, plays Audio Visual Interleaved (AVI) clips. TAnimate works with uncompressed AVI files or AVI clips compressed using run-length encoding (RLE).

TAnimate can obtain its AVI clip from an AVI resource, an AVI file, or, if the application is running under Windows 95 or NT 4.0, from Shell32.dll. To see how TAnimate is used, look at the Webbrows demo application in Coolstuf directory on the Delphi CD.

See Also

About Animate

Animate,


TStaticText
TStaticText1052013

A non-editable text component like Label, except that it includes a window handle, which is useful when the component�s accelerator key must belong to a windowed control.  Use StaticText in ActiveX property pages to provide users with feedback on the current state of the application.

See StaticText


TOpenPictureDialog and TSavePictureDialog
TOpenPictureDialog and TSavePictureDialog1052014

Two new Common Dialog components, TOpenPictureDialog and TSavePictureDialog, appear on the Dialogs palette page. These components work like TOpenDialog and TSaveDialog, except that they include a "preview" region that displays the selected graphic file before opening or saving it.

See Also

OpenPictureDialog

Selecting files to open

SavePictureDialog

Saving files


Decision support components
Decision support components1052015

In Delphi Client/Server, a new group of components facilitates data analysis for decision support. These components include TDecisionCube, a multidimensional array that caches cross-tabulated data from a dataset; TDecisionQuery, a special dataset object that simplifies use of Decision Cubes; TDecisionSource, which represents a pivot state on data from a Decision Cube; TDecisionGrid, which displays cross-tabulated data from a Decision Source; and TDecisionGraph, which displays Decision-Source data in dynamic graphs.

See Also

DecisionCube

Using decision cubes

DecisionQuery

Using decision queries

DecisionSource

Using decision sources

DecisionPivot

Using decision pivots

DecisionGrid

Creating decision grids

Using decision grids

DecisionGraph

Using decision graphs


Input Method Editor (IME) Support
Input Method Editor (IME) support1052016

Visual components that support entry or editing of text now have two published properties that allow you to create IME-enabled controls for Asian-language versions of Windows:

ImeName, which points to an input method editor, lets you to select an IME specifically for the component.

ImeMode controls the behavior of the IME.


Graphics enhancements
Graphics enhancements1052017

The following changes and enhancements have been made to Delphi's graphics support:

The InitGraphics routine is no longer required and has been deleted from graphics.pas.

Thread-safe support has been added for multithreaded operations to graphics classes.

TCanvas has two new methods: Lock and Unlock. The Lock method grabs exclusive access to a drawing canvas, and Unlock releases it. Background threads should always lock a canvas before drawing to it. The VCL will be updated to lock the canvas implicitly during normal VCL painting operations (Paint method and OnPaint events).

Bitmap objects have implicit thread locks only in the Assign operation. If you need to have multiple threads writing to the same bitmap object, you should lock the bitmap's canvas to synchronize access to the bitmap.

New properties have been added to TBitMap:

property DIBMemory: Pointer;

This returns a pointer to the image pixel data in memory for direct modification of the image. This property is read-only.

TBitmapHandleType = (bmDIB, bmDDB);

property HandleType: TBitmapHandleType;

Changing HandleType converts an internal bitmap handle from DIB to device format, or vice-versa. Some color formatting may be lost in the conversion.

TBitmap has been enhanced to use DIB sections instead of memory streams. This reduces system memory use by 50% and preserves the pixel format of the original file even through bitmap modifications.

Support has been added for 15bpp, 16bpp, and 32bpp BMP pixel formats, and for optional color palettes in high-color BMP files. Palettes assigned to high-color bitmaps will be stored in the BMP file. Dithering and halftone palettes are supported when the destination bpp is less than the source bpp.

Palette realization has been removed from bitmap loading code. This eliminates screen flicker when loading forms with 256-color bitmaps, and improves bitmap and form load times by a factor of ten or more in large applications.

TGraphic has two new properties. Graphic objects besides TBitmap can now indicate palette and transparency:

property Transparent: Boolean;

property Palette: HPALETTE.

When Transparent is True, the image does not completely cover its rectangular area.

The read-only property Palette is a handle to the color palette of the image. If the graphic doesn't use palettes,Palette is 0.

TImage no longer assumes TBitmap's palette and transparency settings. Instead it uses TGraphic's generic Palette and Transparent properties. TImage.PictureChanged now initiates a palette realization, if necessary.


TThreadList
TThreadList1052018

A new class, TThreadList, creates a thread-safe list. You can add or remove objects without explicit locks.


Button and Tool Bar components
Button and Tool Bar components1052019

Several new components and properties offer increased options for configuring buttons and tool bars. TToolBar and TCoolBar (on the Win32 palette page) offer improved control over the alignment of buttons at runtime. The Flat property of TToolBar, if set to True, lets graphics show through from under the tool bar. TSpeedButton also has a property called Flat that makes a button's border invisible until the user points to it with the mouse.

To see how TToolBar and TCoolBar work, look at the Webbrows demo application in Demos\Coolstuf on the Delphi CD. (This application, which also illustrates the TAnimate component, is similar to the Webbrows demo in Demos\Internet\Html.)

Note:	Deployment of TCoolBar, or of TToolBar with the Flat property set to True, requires the latest version of COMCTL32.DLL (version 4.70, dated 8/9/96, approximately 370Kb). This file is available from Microsoft; if you've installed Internet Explorer 3.0 or MS Office 97, you already have it.

See Also

Working with toolbars and cool bars.

ToolBar

About ToolBar

CoolBar

About CoolBar


TOleContainer
TOleContainer1052020

A new published property, AllowActiveDoc, has been added to TOleContainer. Set AllowActiveDoc to True to allow insertion of ActiveDocs (DocObjects) into the OleContainer; the OleContainer can respond when an embedded object requests an ActiveDoc interface.


IconFont, UpdateMetricSettings, and CMSysFontChanged
IconFont, UpdateMetricSettings, and CMSysFontChanged1052021

The IconFont property has been added to TScreen, and the UpdateMetricSettings property has been added to TApplication. These properties allow applications to use the Windows 95 Display Properties settings.

IconFont stores the icon font setting from Windows 95, and, if UpdateMetricSettings is True (the default), notifies top-level forms when the setting changes.

TControl has a new DesktopFont property.  When DesktopFont is True, TControl implements the CMSysFontChanged event to reset the Font property.


DataSets
DataSets1052022

A new public property has been added to TDataSet:

property CacheBlobs: Boolean; default True;

Setting this to True turns on blob caching, which improves performance when scrolling through records with on-screen blob fields (for example, in a DBCtrlGrid). Additional memory is used to store the cache.

In preparation for extending the functionality of datasets, BDE-specific dependencies have been removed from TDataSet and put into a new object, TDBDataSet. Some additional functionality is now found in TDBDataSet instead of TDataSet.TDataSet itself contains three new functions:

function IsEmpty: Boolean;

Checks for a dataset without records

function CompareBookmarks(Bookmark1, Bookmark2: TBookmark):Integer;

Compares two bookmarks and returns 0 if they are equal}

function BookmarkValid(Bookmark: TBookmark): Boolean;

Verifies that a bookmark is valid

All dataset code in DB.PAS that depends on the BDE has been moved from DB.PAS into DBTABLES.PAS. Existing code may have to be edited to convert references to variables of TDataSet to TDBDataSet or TBDEDataSet. Some methods and properties  have been moved from TDataSet to TDBDataSet or TBDEDataSet.

Note:	For dataset provider and InterBase tables, resolving a deleted or modified record requires a unique maintained index.


TField
TField1052023

A new function, IsBlob, has been added to TField:

function IsBlob: Boolean;

IsBlob returns True if the field is a blob field.


TClientDataSet
TClientDataSet1052024

A new component, TClientDataSet, is used for multi-tiered database applications.

A new demo application (on the Delphi CD in Demos\Memdata) uses TClientDataSet to create an editable employee table. The client application is in EMPEDIT.DPR and the server application is in EMPSERV.DPR.

See Also

TClientDataSet

Distributed Datasets

Creating and using a client dataset


DBRichEdit
DBRichEdit1052025

The TDBRichEdit component (in the DBCtrls unit) permits the user to display and enter Rich Text Format (RTF) data in a memo or BLOB field.

TDBRichEdit = class(TCustomRichEdit)

Link the TDBRichEdit instance with a dataset by specifying a datasource component (TDataSource) that identifies the dataset as the value of the memo's DataSource property. Specify the field in the dataset  to access as the value of the DataField property. See the TDBMemo documention for further information on connecting the TDBRichEdit to a data source.

Applications must implement any user interface components necessary to make formatting operations available to the user. Refer to the RichEdit demo included in the Demos\RichEdit directory.

See Also

DBRichEdit

About DBRichEdit


DBCtrlGrid
DBCtrlGrid1052026

DBCtrlGrid can now contain DBImage or DBMemo controls  as a result of new support for BLOB caching.

A new property has been added to TDBCtrlGrid:

property SelectedColor: TColor default clWindow;

This property sets the color of the selected panel in the TDBCtrlGrid. By default, SelectedColor is the same as the color of the DBCtrlGrid itself.

See Also

DBCtrlGrid

About DBControlGrid.


Distributed datasets
Distributed datasets1052027

Delphi provides a new dataset component, TClientDataSet, that enables you to create database-independent dataset objects in your applications. Client datasets can be used in standalone, single-tiered database applications, or can be coupled with the new remote server component, TRemoteServer, to create the client portion of multi-tiered database applications.

See Also

TClientDataSet

Creating and using a client dataset

TRemoteServer

Establishing and maintaining a connection to an application server


COM support and ActiveX creation
COM support and ActiveX creation1052028

Delphi provides wizards to quickly create industry-standard ActiveX controls from a VCL (Visual Component Library) control. ActiveX controls can be used with existing development tools, such as C++, Java, Visual Basic, or PowerBuilder. The ActiveForm wizard enables you to quickly convert a Delphi form into an ActiveX control container for other VCL controls. Wizards also allow you to deploy these ActiveX controls and ActiveForms to your Web site. The built-in Component Object Model (COM)support enables developers to create reusable, language interoperable business objects.

See Also

ActiveX classes and demo applications

Internet and intranet development

OLE and ActiveX overview

Creating ActiveX controls

Creating ActiveForms

ActiveX Web Deployment

ActiveX demos

TOleContainer

TStaticText


ActiveX classes and demo applications
ActiveX classes and demo applications1052029

Delphi includes ActiveX demos, an ActiveX Class Framework, and new tools to facilitate building ActiveX controls. To find the new tools, choose File|New and click the ActiveX tab.

Two ActiveX demos are included:

DelCtrls (in Demos\ActiveX\Delctrls) includes many standard Delphi components in an ActiveX control.

TRegSvr (in Demos\ActiveX\Tregsvr) is a utility that registers ActiveX servers.


Internet and Intranet development
Internet and Intranet development1052030

If you have the Client/Server edition, Delphi provides you with several new components that make building Internet and Intranet applications easy. These components handle all communication with the Web server, so you can concentrate on the content of your Web server application without having to worry about the HTTP communications protocols. Specialized table producers create HTML to represent your datasets, while page producers organize other HTML content. If you want to build a specialized server or client application, socket components handle the low-level communications protocols, allowing you to concentrate on the service your application is providing.

See Also

Creating Internet server applications

Working with sockets

Internet components

Internet component demos


Internet component demos
Internet component demos1052031

New components have been added to enable the creation of Internet server DLLs.

The Chat demo (in Delphi 3\Demos\ Internet\Chat) uses some of these components in a "Chat" application.

The WebServ demo (in Demos\Webserv) uses the new Internet components to create an ISAPI Web-server application; the first Web page shows a list of customers and company names, with hypertext links to each company's Web page.

Note:	A single project should not include both the Forms unit and the HTTPApp unit. Each of these units declares its own Application variable (TApplication in Forms and TWebApplication in HTTPApp), which Delphi uses for initialization on program startup. Including both units in a project will cause a runtime error.

Note:	Under Windows NT, you must have the correct user rights to debug a  DLL that is launched from a Web Server.. In the User Manager

1.	Choose Policies|User Rights.

2.	Select "Show advanced user rights".

3.	Choose "Act as part of the operating system" in the "Right" list.

4.	Add your name to the "Grant To" list.

See Also

Creating Internet server applications

Working with sockets

Internet components

Internet and intranet development


RTL enhancements
Run Time Library enhancements1052032

Math Unit

New integer functions have been added to the Math unit:

function SumInt(const Data: array of Integer): Integer register;

function MinIntValue(const Data: array of Integer): Integer;

function MaxIntValue(const Data: array of Integer): Integer;

These functions work like the corresponding floating-point functions Sum, MinValue, and MaxValue.

System Unit

See Compiler Changes.

SysUtils Unit

The SysUtils unit contains new functions and procedures:

function CompareMem(P1, P2: Pointer; Length: Integer): Boolean;
assembler.

CompareMem compares Length bytes of memory referenced by P1 to Length bytes of memory referenced by P2, and returns True if the memory segments are the same.

procedure RaiseLastWin32Error;

procedure Win32Check(RetVal: BOOL);

RaiseLastWin32Error retrieves the code for the last occurring Win32 error and raises an exception with the error code and associated message. Win32Check is used to verify the value of any Win32 API function that returns a BOOL to indicate success; if the function returns False (indicating failure), Win32Check calls RaiseLastWin32Error to raise an exception.


Multibyte character support
Multibyte character support1052033

Several functions have been added or modified in the run time library to support multibyte characters. AnsiLowerCase, AnsiUpperCase, ChangeFileText, ExtractFileDir, ExtractFileExt, ExtractFileName, and ExtractFilePath have been modified.

The following functions are new:

AnsiCompareFileName	AnsiExtractQuotedStr

AnsiLastChar	AnsiLowerCaseFileName

AnsiPos	AnsiQuotedStr

AnsiStrComp	AnsiStrIComp

AnsiStrLastChar	AnsiStrLComp

AnsiStrLIComp	AnsiStrLower

AnsiStrPos	AnsiStrRScan

AnsiStrScan	AnsiStrUpper

AnsiUpperCaseFileName	ByteToCharIndex

ByteToCharLen	ByteType

CharToByteIndex	CharToByteLen

IsDelimiter	IsPathDelimiter

LastDelimiter	StrByteType

Note:	The ByteType and StrByteType functions require an index parameter, but do not perform bounds checking. Hence, passing a very large number to one of these functions can cause an access violation.

Finally, the LeadBytes global variable has been added:

LeadBytes: set of Char = [];

TFont.Charset property
When using a multibyte character set, set the TFont.Charset property.

Charset is an integer that represents the character set selected for the text object where the TFont instance occurs. For Asian characters to display properly, Charset must point to a character set that contains those characters. The easiest way to set Charset is to open the Object Inspector's Font dialog for the text object (such as TLabel) and select a font from the list box.

The TTextAttributes object used by Rich Edit controls also supports the Charset property.


New Borland Database Engine (BDE) and SQL Links
New Borland Database Engine (BDE) and SQL Links1052034

Delphi includes a new versions of the BDE 4.0 and SQL Links. Most files associated with the BDE are in \Program Files\Borland\Delphi 3\BDE. For information about BDE and SQL Links 4.0, see Readlink.txt. Help for the BDE is in BDE32.HLP and BDE32.CNT.

To configure the BDE, you can launch the following driver configuration utilities from within the Database Explorer:

ODBC Administrator for ODBC drives: Click Databases at the top of the Databases tab. Then choose Object | ODBC Administrator.

Vendor-supplied configuration utilities for SQL drives: Click an alias on the Databases tab. Then choose Object | Vendor Configuration (or the name of the target utility, if it appears).

BDE Administrator for the BDE and native BDE/SQL Links drivers: Choose Object | BDE Administrator. Online Help for the the BDE Administrator (BDEADMIN.EXE) is in BDEADMIN.HLP and BDEADMIN.CNT.

New BDE features include:

FoxPro support

The dBASE driver now includes support for FoxPro compressed index (.CDX) and BLOB (.FPT) files, letting you open and create  FoxPro 2.0, 2.5, and 2.6 tables. To create a FoxPro table with the dBASE driver, set the LEVEL driver configuration parameter to 25 using the Configuration page of the BDE Administrator.

To create FoxPro tables using the BDE API, pass the optional parameter LEVEL with a value of 25 when using DbiCreateTable to create a dBASE table.

To add a FoxPro index, set curTABLELEVEL  to 25 using DbiSetProp before calling DbiAddIndex. DbiSetProp will return an error if the table is already using dBASE index or BLOB files.

To see if a cursor is referencing a FoxPro table, retrieve CURProps using DbiGetCursorProps and check if CURProps.iTblLevel is equal to FOXLEVEL25.

Microsoft Access support

If you have a version of the Microsoft JET engine (included with Microsoft Access and FoxPro) installed on your system, you can now use the BDE to open or create Microsoft Access tables using the MSACCESS driver.

Note:	BCD (binary coded decimal) support is not yet implemented for this driver. Setting the BCD Enabled parameter to True has no effect.

In the BDE API, use the constant szMSACCESS when creating Access tables or checking the table type. The following table lists new physical data types for MSACCESS and their BDE logical equivalents:

MSACCESS Physical Datatype	BDE Logical Equivalent

fdACCAUTOINC	fldINT32, fldstAUTOINC

fldACCBIT	fldBOOL

fldACCBYTE	fldUINT16

fldACCCHAR	fldZSTRING

fldACCDATETIME	fldTIMESTAMP

fldACCDOUBLE	fldFLOAT

fldACCFLOAT	fldFLOAT

fldACCLONG	fldINT32

fldACCLONGBINARY	fldBLOB, fldstACCOLEOBJ

fldACCLONGTEXT	fldBLOB, fldstMEMO

fldACCMONEY	fldFLOAT, fldstMONEY

fldACCSHORT	fldINT16

fldACCVARCHAR	fldZSTRING

ODBC 3.0 support

The new BDE supports ODBC 3.0 drivers.

Multibyte character support

The new BDE is fully multibyte-enabled.

BDE Provider support

The BDE Provider technology is used by Delphi's new distributed DataSets. For more, see Understanding BDE-enabled datasets

Data Dictionary enhancements

The Data Dictionary can now store domain and table constraints. These can be propagated to the client using remote DataSets or enforced using BDE cursors.

Parameter binding support for BLOBs and long strings (greater than 255 characters)

BDE now supports parameter binding for BLOBs and strings longer than 255 characters. See the description of DbiQSetParams in BDE32.HLP for details.

Oracle 7.3 stored procedures

Oracle 7.3 stored procedures can now return result sets.

SQL Monitor

The SQL Monitor now provides more information on SQL transactions.

Configurable BLOB caching

You can now use the Database Explorer to configure the BDE�s BLOB caching.

See Also

DataSets

TField

TClientDataSet

DBCtrlGrid

DBRichEdit

Distributed datasets


SQL Database Explorer Enhancements
SQL Database Explorer Enhancements1052035

The following features have been added or enhanced in the SQL Database Explorer:

BDE administration

The SQL Database Explorer includes a page tab for configuring the Borland Database Engine.

SQL editing

Editing of some SQL objects (such as tables, views and stored procedures for all servers, Oracle packages and package bodies, InterBase generators and exceptions) is now supported.

Object menu commands that affect SQL objects include New, Rename, Delete, Apply, Cancel, and Save As. Remember that edits are temporary until they are applied. Back up your data before editing SQL objects.

View | Change Text Option

As you edit an SQL object, you can see the queries that will be executed when you apply your changes. The queries are listed in a read-only Changes area on the Text page. To show the Changes area, select View | Change Text.

SQL editing in the IDE Code Editor

If you invoke the SQL Database Explorer from the Delphi IDE, you can use the Code editor and its rich set of editing features to edit SQL objects. To use the Code editor,

1.	Choose Database | Explore.

2.	Select and SQL object to edit.

3.	Choose Edit | Text (ctrl-T) from the Explorer menu.

While you edit an SQL object in the code editor, the object's text is read-only in the Database Explorer.

Query Options

A new Query Options dialog (select Options | Query) sets options for queries executed on the Enter SQL page. The Live Queries option has been moved from the Options menu to the Query Options dialog. New options control the execution of query scripts, allowing you to configure the Database Explorer for limited compatibility with tools from server vendors such as Sybase isql.exe and Microsoft SQL Server saf.exe. (For example, to configure the Database Explorer for use with Sybase isql.exe, you would set the line delimiter to "go".) By default, the line delimiter is "---" and no statement delimiter is defined; a typical statement delimiter would be ";".

Save As Dialog

A new Save As menu item invokes a Save As dialog where you can specify a name for the SQL object to save. By default an object's current name is proposed. If you keep the current name, any changes you have made are applied to the current object. If you specify a new name, a new object is created and any editing changes are applied to the new object. Edits to the original object remain intact, but are not applied to the original object until you choose to apply them.

Saving Text to Files

If an SQL object has a text representation on the Text page, the local menu contains a Save Text to File command that enables you to save the object's text to a text file.

You can also save a change script to a text file, which can be useful when you want to reuse the script on different systems with the same SQL object. To save a change script, click or tab into the change script and choose Save Text to File.

Unless the change script is selected, choosing Save Text to File saves the object, not the script.

Data Page Local Menu Commands

The following commands have been added to the local menu for the Data page: Order, Range, and Filter. These commands invoke dialogs that let you specify data ordering, set a range, or filter a data set. When you explore a different SQL object, Order, Range, and Filter are automatically reset.

Object-specific Local Menus

Local menus now have object- and platform-specific commands for some objects. For example, when you are editing an Oracle package heading, function, or procedure, a Compile command appears on the local menu.

Filter and Transaction Control

The Enter SQL local menu provides the following commands for controlling filtering and transactions: Filter, Begin Transaction (or Commit Transaction and Rollback Transaction). To specify an isolation level for a transaction, choose Options | Transaction Isolation.

Drag-and-Drop Stored Procedures

Stored procedures are now available as a drag-and-drop source. You can create a TStoredProc component by dragging a stored procedure from the Database Explorer onto a Delphi form, just as you would with databases, tables, views, and columns.

Support for DB2 and Informix

The Database Explorer now supports DB2 for common servers and Informix 5, 6, and 7. DB2 support is also planned for MVS and AS/400.

Word Wrap

A Word Wrap option has been added to the Options menu. Select Word Wrap if you want text to wrap on the Text page. This option is especially useful for DB2 and Informix servers, which don't save the original line breaks for objects such as views.


OLEnterprise with Business Object Broker
OLEnterprise with Business Object Broker1052036

Delphi Client/Server includes OLEnterprise, which provides an OLE/DCOM interface to any RPC or COM server. OLEnterprise lets application logic and data access be centralized on an application server; the server becomes a one-to-many provider of distributed business objects and processes.The Object Broker distributed name service indirectly binds applications to remote objects based on object availability.

Note:	Purchase of Delphi Client/Server does not include redeployment rights for OLEnterprise or the Business Object Broker. If you wish to deploy applications that use OLEnterprise, you must purchase separate deployment licenses. Contact your local Borland sales office for details.

OLEnterprise is installed separately from Delphi. The files are on the CD in the \Olent directory, which includes additional documentation. For installation instructions,see INSTALL.TXT. For more information about OLEnterprise, see Open Environment's Web site at http://www.openenv.com/.


Compiler changes
Compiler changes1052037

Package Support

Language extensions and compiler directives have been added to support packages.

See Using Packages

Interfaces

Language extensions have been added to support development of COM and ActiveX objects.

See OLE and ActiveX overview

Assertions

Assert is a standard procedure, declared in the System unit, that tests whether a Boolean expression is successful:

Assert(expr: Boolean [; msg: string]);

If the Boolean test fails Assert raises an exception. (EAssertionFailed is declared in the Sysutils unit.)

Assertions are a debugging tool. Use them to test for preconditions that should not fail. Assert provides an opportunity to intercept a condition that should halt a program and that might otherwise cause abnormal termination. If no user code catches the EAssertionFailed, then the RTL will issue runtime error 227 and halt the program.

Since assertions are not usually used at run-time in shipping versions of a product, compiler directives are provided that disable the generation of code for assertions. They are:

$ASSERTIONS ON/OFF	(long form)

$C +/- (short form)

These are global switches and take effect for the whole source file in which they are contained, regardless of their position in the file.  It is not possible to enable and disable assertions for something smaller than a source file.

Boolean Data Types

For compatibility with Visual Basic, the True value for data types ByteBool, WordBool, and LongBool is now represented as -1; False is still represented as 0. Internally, the compiler gives these data types the same range as Integer. Every effort has been made to minimize the code revision required to accommodate this change. However, bounds checking is no longer implemented for these types. If typecasting has been used, code may no longer work properly. Short-circuit evaluation functions as before.

The Boolean data type remains unchanged (True = 1, False = 0).


New demo applications
New demo applications1052038

The following new demos are Installed with Delphi in the Delphi 3\Demos\... directory:

CHAT (in ...\Internet\Chat) is an Internet Chat application.

DelCtrls (in ...\ActiveX\Delctrls) includes standard Delphi components in an ActiveX control.

TRegSvr (in ...\ActiveX\Tregsvr) is a utility that registers ActiveX servers.

Webbrows (in ...\Coolstuf) uses the new TToolBar, TCoolBar, and TAnimate components in a Web browser.

EmpEdit (in ...\Memdata) uses TClientDataSet to create an editable employee table.

WebServ (in ...\Webserv) is a Web-server database application.

For more information about demo applications, see Readme.txt.

Additional demos can be found on the Borland Web site


Miscellaneous IDE enhancements
Miscellaneous IDE enhancements1052039

DLL Debugging

You can now specify an .EXE file to run for the purpose of debugging a DLL project. Choose Run | Parameters and enter the name of the .EXE file in the "Host application" edit box.

Unit Output Directory

The Directories/Conditionals page of the Project Options dialog has a new edit box called Unit Output Directory. Use this to specify the directory where compiled unit files are stored. Project .DLL and .EXE files are still sent to the regular Output Directory.

Shared Repository Directory

The Preferences page (under Tools | Options) now has an edit box for specifying the Shared Repository Directory. This location is stored in the Windows registry. In Delphi 2.0 it had to be be changed manually in the Windows Registry Editor (by creating a String Value called "BaseDir" in the "HKEY_CURRENT_USER | Software | Borland | Delphi | 2.0 | Repository" key).

Version Information

You can now include version information in your Delphi projects. Click the VersionInfo tab in the Project Options dialog (Project | Options) and select Include Version Information in Project. In addition to updating version information manually before recompiling a project, you can select the Auto-increment Build Number option. Version information appears on the Version page of the Windows Properties dialog for the project's .EXE file.

Compatibility Issues

Some of the changes introduced by Delphi 3 may require a few adjustments to your Delphi 2 applications.  See Compatibility with Version 2 for detailed information.


Compatibility With Version 2
Compatibility With Version 21052040

Where possible, Delphi tries to provide backward compatibility with previous versions. Some of the new features in Delphi 3, however, require changes to the way applications are put together. Click here for a list of topics that are intended to ease the migration path of your application to Delphi 3.


Component Palette changes
Component Palette changes1052041

See Also

Some components have been renamed, replaced, or moved to different palette pages.

The Win95 palette page is now called Win32, and contains additional controls.

The OCX page is now called ActiveX. The components on that page have changed as well.

VSSpell has been replaced by VCSpeller.

F1Book has been replaced by VCFormulaOne.

VtChart has been replaced by VCFirstImpression.

Graph has been replaced by GraphicsServer.

The FileListBox, DirectoryListBox, DriveComboBox, and FilterComboBox controls have moved from the System palette page to the Win 3.1 palette page.

Report has been removed from the Data Access page.  The Report component is still available for backward compatibility, but new applications should use the reporting components on the QReport page.

Check the Register procedure for your components, to see what Palette page they are installed on. If the Register procedure specifies a palette page that doesn�t exist, Delphi creates a new page. In some cases, this is what you want, but in other cases, the component is being registered on a page that has been renamed or replaced. For example, if your unit file contains the line

RegisterComponents(�Win95�, [TNewComponent]);

replace it with

RegisterComponents(�Win32�, [TNewComponent]);

to move your component to the renamed palette page.


Database changes
Database changes1052042

See Also

In order to prepare for extending the functionality of datasets, dependencies on the Borland Database Engine (BDE) have been removed from TDataSet and put into a new object, TBDEDataSet.  If your code refers to the TDataSet class, you may need to change it so that it references TBDEDataSet instead.  The following methods and properties have been moved from TDataSet to TDBDataSet or TBDEDataSet:

procedure GetIndexInfo;	procedure FetchAll;
procedure ApplyUpdates;	procedure CommitUpdates;
procedure CancelUpdates;	procedure RevertRecords;
function UpdateStatus: TupdateStatus;	property UpdatesPending: Boolean;
property Handle: HDBICur;	property Locale: TLocale;
property UpdateObject: TdataSetUpdateObject;	property UpdateRecordTypes: TUpdateRecordTypes;
property ExpIndex: Boolean;	property KeySize: Word;
property SetDetailFields;
All dataset code in the DB unit that depends on the BDE has been moved to the DBTables unit, and the field component classes have been moved from the DBTables unit back to the DB unit.  You may need to change the uses clause in your files to include the DBTables unit. The following is a list of objects that have been moved from the DB unit to DBTables:

EDBEngineError	TDBError

TBDECallback	TLocale

TDatabase	TParamList

TDataSetUpdateObject	TSession

TDBDataSet	TSessionList

In addition to the field components (TAutoIncField, TBCDField, and so on), TIndexDef and TIndexDefs have moved from the DBTables unit to the DB unit.

The BDECalcField property has been removed from TField.  Use the expanded FieldKind property instead.  For TFieldDef, the BDECalcField property has been generalized and renamed to InternalCalcField.  The Transliterate property has been moved from TMemoField to its immediate ancestor TBlobField.


Changes to other objects
Changes to other objects1052043

See Also

In addition to the changes in the data access components, some of the other objects in the Component library have  changed.  In most cases, code that uses the older components is automatically converted.  However, you may wish to check for the following cases.

TTreeView

The OnExpanded, OnExpanding, OnCollapsed, and OnCollapsing events now occur in all parent nodes no matter how the nodes are expanded or collapsed.

TForm

The TForm class has been divided into a TCustomForm base class and a TForm derived class.  In most cases, this change will not affect your code.  However, the global GetParentForm function now returns a TCustomForm object instead of a TForm object.  In addition, the form�s GetChildren method now has an additional parameter that specifies the form that must be searched.

ActiveX

Delphi 3 introduces new ActiveX wrapper classes to allow you much more power and flexibility when creating ActiveX controls.  The old Delphi 2 classes are still provided for backward compatibility.  Include the  OleAuto unit when you are using the Delphi 2 ActiveX objects.

QuickReports

Most reports designed with QuickReport 1.0 are automatically converted at design time to version 2.0.  However, the conversion process has some limitations.  Some reports from Delphi 2.0 may not load properly.

Graphics unit

The InitGraphics routine is no longer required and has been deleted from graphics.pas.

Errors

EOutOfResources and EInvalidOperation exception classes have moved from controls.pas to classes.pas.

TPropInfo

The PropType field of the TPropInfo record has changed from PTypeInfo to PPTypeInfo.  Component writers that provide design time property editors may need to adjust their code for the additional level of indirection.


Compiler Changes
Compiler Changes1052044

See Also

For compatibility with Visual Basic, the True value for data types ByteBool, WordBool, and LongBool is now represented as -1.  False is still represented as 0.  Internally, the compiler gives these data types the same range as Integer.  Every effort has been made to minimize the code revision required to accomodate this change.  However, bounds checking is no longer implemented for these types.  If your code uses typecasting, it may no longer work properly.  Short-circuit logic behaves as before.  The Boolean data type remains unchanged (True = 1, False = 0).

The new CharSet property on fonts is not recognized by earlier versions of the compiler.  If you save a form in Delphi 3 (even if it was created in Delphi 2), all fonts are given the CharSet attribute set. After saving the form in Delphi 3, trying to run or recompile the form in Delphi 2 will generate an error.  You can tell Delphi 2 to continue running the form in spite of the error, and it will strip out the new property.


Changes to the Help system
Changes to the Help System1052045

See Also

Delphi 3 calls up help for components differently than Delphi 2 did.  If you are writing custom components and providing your own help system, you must use A linking instead of multihelp B footnotes to provide context-sensitive help.  For more information, see Providing context-sensitive help for your component.


Changes introduced by packages
Changes introduced by packages1052046

See Also

Packages are special dynamic-link libraries used by Delphi applications, the Delphi IDE, or both.  They allow code-sharing among applications, reducing executable size and conserving system resources.  The Component Library has been re-engineered to take advantage of package technology.

The introduction of Packages may require some changes to your source code.  In particular, the ExitProc should be used only when generating .EXE files.  Do not use ExitProc within a dynamically loaded package, such as design-time code.  All ExitProc calls are now made before any of the finalization sections are executed.  Use finalization sections to implement exit behavior.  In your existing code, move ExitProc variables to the finalization section.

The use of packages also changes the way you must install third party components (DCUs).  For more information, see Using older third party components.

For more information about compiling and using packages, see Using packages.


Using older third-party components
Using older third-party components (DCUs)1052047

See Also

In Delphi 3, all components are installed in the IDE as packages, which are special DLLs. If you are using third-party components that were supplied for a previous release of Delphi, you can�t install them �as is� in the new IDE. To use your old third-party components in Delphi 3, you must either

Get new (packaged) versions from the component vendor.

Compile the components into a package yourself.

Replace the components with the new or enhanced objects supplied with Delphi 3. Delphi 3 introduces several new objects that extend the functionality of Delphi to take advantage of recent enhancements to Windows.

If you get new, packaged versions of your components, follow the vendor�s instructions for their installation and use.

To compile third-party components into packages on your own, you must have complete source (.PAS) files for the components. If the vendor has supplied a �main� .PAS file that uses another file shipped only as a .DCU, you will not be able to compile the package. If you have several third-party components that you want to install, you can compile them all into a single package.

Before compiling third-party components into packages, check the source code for necessary changes. See the following topics for information on what you should look for:

Database Changes

Changes Introduced by Packages

Component Palette Changes

Compiling and installing a package

To compile a component and install it on the Component palette:

1.	Choose File|New and double-click the Package icon.

2.	In the New Package dialog, enter a file name (you need not include the extension), and, optionally, a description. You can use any valid name for your package file. Click OK.

3.	In the Package editor, select the Contains tab and click Add. With the Add Unit tab selected, enter the name of the component�s main source file in the Unit File Name edit box. Click OK.

4.	If you are including multiple components in a single package, and the components have different source files, repeat step 3 above. However, if the additional units are listed in the Uses clause of the main unit you are packaging, do not add those units to the package, they will be added automatically during compilation.

5.	Click Compile to compile the package. The compiler may ask permission to add other packages to the Requires clause of the package you are building. Click OK.

6.	After successfully compiling the package, click Install to install the components on the Component palette.

7.	Before closing the Package editor, right-click and choose Save Package from the speed menu. This saves the package source (.DPK) file.


Delphi for C++ Programmers
Information about Delphi for C++ programmers1052048

C++ programmers who are new to Delphi should read the white papers in D3_CPP.DOC and BC5_D3.DOC. These Microsoft Word documents are located on the Delphi CD in the Info\Borland directory. For additional information, see Borland's Web site at http://www.borland.com/delphi/cpp/.


Delphi for VB Programmers
Information about Delphi for Visual Basic programmers1052049

Visual Basic programmers who are new to Delphi should read the white paper in VB2DELPH.DOC. This Microsoft Word document is located on the Delphi CD in the Info\Borland directory. For additional information, see Borland's Web site at http://www.borland.com/delphi/vb/.


Getting started1052050

A tour of the Delphi development environment

A tour of the Delphi development environment

Placing components on a form

Changing component appearance and behavior

Editing code with the Delphi Code editor

Debugging applications

Exploring databases

Flexible tool for storing objects as templates

Project file-management tool

Handy pop-up menus

Toolbar buttons for frequently used commands

Getting help

First application--a brief tutorial

First application--a brief tutorial

Starting a new application

Setting a property value at design time

Adding objects to the form

Accessing a database

Adding some spice

Final touches

Hooking up an event handler


Developing Applications1052051

Making effective use of the development environment

Making effective use of the development environment

Browsing and designing with the SQL Explorer

Using the Data Dictionary

Creating multi-tiered database applications

Designing a database interface with data-aware controls

Using the Database Desktop with Paradox and dBASE files

Using data modules and remote data modules

Creating and using component templates

Using the Object Repository

Overview of Delphi's database architecture

Managing database sessions

Managing database sessions

Working with a session component

Managing multiple sessions

Using a session component in data modules

Connecting to databases

Connecting to databases

Understanding persistent and temporary database components

Controlling connections

Handling transactions

Applying cached updates for multiple datasets

Understanding database and session component interactions

Using database components in data modules

Understanding datasets

Understanding datasets

What is TDataSet?

Opening and closing datasets

Determining and setting dataset states

Searching datasets

Displaying and editing a subset of data using filters

Modifying data

Using dataset events

Understanding BDE-enabled datasets

Understanding BDE-enabled datasets

Overview of BDE-enablement

Handling database and session connections

Working with a provider component

Working with cached updates

Caching BLOBs

Responding to a server yield

Creating and using a client dataset

Creating and using a client dataset

Working with a client dataset

Sorting and indexing

Working with another view of a dataset

Creating a new dataset

Working with data sources

Working with data sources

Establishing a database-to-data control link

Working with field components

Working with field components

Understanding field components

Creating persistent fields

Arranging the order of persistent fields

Defining new persistent fields

Setting persistent field properties and events

Working with field component methods at runtime

Displaying, converting, and accessing field values

Checking a field's current value

Setting a default value for a field

Working with constraints

Working with tables

Working with tables

Using table components

Setting up a table component

Controlling read/write access to a table

Searching for records

Sorting records

Working with a subset of data

Deleting all records in a table

Deleting a table

Creating a table

Importing data from another table

Synchronizing tables linked to the same database table

Creating master/detail forms

Working with queries

Working with queries

Using queries effectively

What databases can you access with a query component?

Using a query component: an overview

Specifying the SQL statement to execute

Setting parameters

Executing a query

Preparing a query

Unpreparing a query to release resources

Creating heterogenous queries

Improving query performance

Working with result sets

Working with stored procedures

Working with stored procedures

When should you use stored procedures?

Using a stored procedure

Creating a stored procedure component

Understanding stored procedure parameters

Viewing parameter information at design time

Setting parameter information at design time

Setting input parameter values at run time

Preparing and executing a stored procedure

Binding parameters

Accessing output and result parameters

Accessing the result dataset

Working with Oracle overloaded stored procedures

Working with cached updates

Working with cached updates

Deciding when to use cached updates

Understanding the cached updates process

Enabling and disabling cached updates

Fetching records

Applying cached updates

Canceling pending cached updates

Undeleting a cached record

Checking update status

Determining if you need to control the updating process

Using update objects to update a dataset

Updating a read-only result set

Creating an OnUpdateRecord event handler

Handling cached update errors

Using data controls

Using data controls

Using common data control features

Displaying and editing data in a data-aware control

Displaying data as labels

Displaying and editing fields in an edit box

Displaying and editing text in a memo control

Displaying and editing text in a rich edit memo control

Displaying and editing graphics fields in an image control

Displaying and editing data in list and combo boxes

Displaying and editing data in lookup list and combo boxes

Handling Boolean field values with check boxes

Restricting field values with radio controls

Navigating and manipulating records

Working with grids

Working with grids

Viewing and editing data with TDBGrid

Creating a grid that contains other data-aware controls

Using decision support components

Using decision support components

About crosstabs

Guidelines for using decision support components

Using datasets with decision support components

Using decision cubes

Using decision sources

Using decision pivots

Creating and using decision grids

Creating and using decision graphs

Decision support components at runtime

Decision support components and memory control

Copying data and table structures

Copying data and table structures

Creating a batch move component

Specifying a batch move mode

Mapping data types

Executing a batch move

Handling batch move errors

Creating a multi-tiered application

Creating a multi-tiered application

A structural overview of a multi-tiered application

Advantages of the multi-tiered database model

Overview of creating a multi-tiered application

Establishing and maintaining a connection to an application server

Accessing data with client datasets

Creating a data provider for the application server

Supporting the briefcase model

Modifying a two-tiered application to use the multi-tiered model

2 Creating custom components

Overview of component creation

Overview of component creation

The Visual Component Library

Components and classes

How do you create components?

What goes in a component?

Creating a new component

Testing uninstalled components

Object-oriented programming for component writers

Object-oriented programming for component writers

Creating new classes

Ancestors, descendants, and class hierarchies

Controlling access

Dispatching methods

Abstract class members

Classes and pointers

Creating properties

Creating properties

Why create properties?

Types of properties

Publishing inherited properties

Defining properties

Creating array properties

Writing property editors

Creating events

Creating events

What are events?

Implementing the standard events

Defining your own events

Creating methods

Creating methods

Avoiding dependencies

Naming methods

Protecting methods

Making methods virtual

Declaring methods

Using graphics in components

Using graphics in components

Overview of graphics

Using the canvas

Working with pictures

Offscreen bitmaps

Responding to changes

Handling messages

Handling messages

Understanding the message-handling system

Changing message handling

Creating new message handlers

Registering components

Registering components

Registering components

Adding palette bitmaps

Providing Help for your component

Storing and loading properties

Creating packages

Creating packages

Runtime and design-time packages

Modifying an existing component

Modifying an existing component

Creating and registering the component

Modifying the component class

Creating a graphic component

Creating a graphic component

Creating and registering the component

Publishing inherited properties

Adding graphic capabilities

Customizing a grid

Customizing a grid

Creating and registering the component

Publishing inherited properties

Changing initial values

Resizing the cells

Filling in the cells

Navigating months and years

Navigating days

Making a control data-aware

Making a control data-aware

Creating a data-browsing control

Creating a data-editing control

Making a dialog box a component

Making a dialog box a component

Defining the component interface

Creating and registering the component

Creating the component interface

Testing the component

Building a dialog box into a DLL

Building a dialog box into a DLL

Adding the interface routine

Modifying Project file

Opening the dialog box from an application

2 Creating Internet and intranet applications

Creating Internet server applications

Creating Internet server applications

Terminology and standards

An overview of HTTP server activity

Web server applications

The structure of a Web server application

The Web dispatcher

Action items

Accessing client request information

Creating HTTP response messages

Generating the content of response messages

Using database information in responses

Debugging server applications

Working with sockets

Working with sockets

Implementing services

Describing socket connections

Describing the socket

Using socket components

Reading and writing over socket connections

Responding to socket events

2 Working with COM and ActiveX

OLE and ActiveX Overview

OLE and ActiveX Overview

An Overview of COM

Using interfaces in Delphi

OLE and ActiveX objects

OLE Automation interfaces

Delphi ActiveX Framework

Creating ActiveX controls

Creating ActiveX controls

Overview of ActiveX control creation

Creating an ActiveX control

Creating ActiveForms

Creating ActiveForms

Creating an ActiveForm

ActiveX Web Deployment

ActiveX Web Deployment

Deploying ActiveForms and ActiveX controls

Setting Web Deployment Options

Creating property pages

Creating property pages

Creating a property page

Creating OLE Automation servers

Creating OLE Automation servers

Overview of Automation server creation

Creating an Automation server

Working with type libraries

Working with type libraries

The Type Library editor


Workgroups menu
Workgroups menu: Delphi version control interface1037001

Use the Workgroups menu to set up version control and manage workflow on projects involving many programmers. Delphi version control is an interface to Intersolv PVCS Version Manager 5.1 or later.

Workgroups menu commands:

Browse PVCS Projects	Displays the PVCS Project window in which you can perform all version control tasks and access help.
Manage Archive Directories	When the PVCS window is open, displays the Archive Directories dialog box that lets you add, remove, or create archive directories.
Add Project to Version Control	Lets you save the current project to a version control directory.
Set Data Directories	Displays the Data Directories dialog box to set location of public and private root directories.
Why use version control?

After you have created more than one application or source code file with Delphi, version control helps you organize and keep track of the programs. You might want to archive old versions of an application before you start to work on the new version. If you work with a team of programmers, you need a way to coordinate which programmers have access to certain files, so that one programmer does not accidentally lose, change, or overwrite another programmer's code.

A version control system is useful when managing multiple or complex programming projects. Version control is used to archive files, control access to files by locking, and manage multiple versions of your projects.

PVCS Version Manager lets you store all the successive revisions of each file in an archive. Each project consists of a set of archives. Programmers checkout working files (努orkfiles�)  from the archives, modify them, then check them back in, indicating revisions made, author, and date.  The locking features of checkin and checkout prevent overwrites and out-of-sync problems.  Also, you can track which changes were made at every stage to every file in a project: the who, what, when, and why of every modification.

Note:	Team development support is included in Delphi Client/Server. If you install the PVCS Developer Toolkit or Version Manager programs after installing Delphi, see Enabling PVCS support


Enabling PVCS support
Enabling PVCS support1037002

Delphi's version control system support should be enabled when you run the setup program.

However, if you install the PVCS Developer Toolkit or Version Manager programs after installing Delphi, you must:

1. le DELPHI.INI in your Windows directory:

[Version Control]

VCSManager=C:\Program Files\Borland\Delphi\Bin\STDVCS32.DLL

Note that the path given above should specify the directory in which you installed Delphi. If necessary, replace C:\Program Files\Borland\Delphi\Bin (the default) with the path required by your system.

Note that the PVCS runtime DLL痴 must be on your DOS path for Delphi to find them.

1. enu bar.

1. kgroups | Browse PVCS Projects to display PVCS Project window.

2. Manager.


Workgroups|Manage Archive Directories
Workgroups | Manage Archive Directories1037003

See also

With the PVCS window open and a project selected in the left pane, choose Workgroups|Manage Archive Directories to specify or create directories for the PVCS Version Control archives that make up a project.  An archive stores all the successive revisions of an individual workfile.  Developers checkout workfiles from the archives, modify them, then check them back in, indicating revisions made, author, and date.

To use the Manage Archive Directories dialog box:

1.	Specify an archive directory in the Directory and Drives lists.

2.	To designate the specified directory an archive location, click Add.

3.	To remove an archive location from the Archive directories list, click Remove.

4.	Choose OK to save the archive directory specification.


Workgroups|Add Project To Version Control
Workgroups | Add Project to Version Control1037004

See also

Choose Workgroups|Add Project to Version Control to create a new PVCS project for the current Delphi Project.


Workgroups|Browse PVCS Project
Workgroups | Browse PVCS Project1037005

See also

Choose WorkgroupsIBrowse PVCS Projects to display the PVCS Project window in which you can perform all version control tasks. You can check in or check out files, add, edit, or remove labels, lock or unlock revisions, run visual comparison, and archive reports. The Help icon opens the PVCS Help system for details on version control tasks.


Mworkgroups|Set Data Directories
Workgroups | Set Data Directories1037006

See also

Choose Workgroups|Set Data Directories to set directories for workfiles.  When you check out a workfile from the archive, it is located in the directory you specify in this dialog box.


Custom Expert menu item

You have pressed F1 on a menu item for an Expert that was installed externally. For more information regarding this item, select it to open the Expert. Help is available for externally installed Experts if provided by the developer of the Expert.


Custom Version Control menu item

You have pressed F1 on a menu item for a version control system that was installed externally. For more information regarding this item, select it to gain access to the version control system. Help may be available for your version control system depending on the particular installation.


See also1037007

Workgroups menu

Workgroups|Browse PVCS Project

Workgroups|Add Project To Version Control

In the PVCS window, click the Help icon.

Enabling PVCS support


See also1037008

Workgroups menu

Workgroups|Browse PVCS Project

Workgroups|Manage Archive Directories

In the PVCS window, click the Help icon.

Enabling PVCS support


See also1037009

Workgroups menu

Workgroups|Manage Archive Directories

Workgroups|Add Project To Version Control

In the PVCS window, click the Help icon.

Enabling PVCS support


A tour of the Delphi development environment
A tour of the Delphi development environment1060001

Section topics	参照

Windows ベースのアプリケーションと同じように次の方法で Delphi を起動できます。

インストールプログラムで作成されたアイコンをダブルクリックします。

DELPHI32.EXE ファイルをダブルクリックします (デフォルトでは，インストール時にこのファイルは \ProgramFiles\Borland\Delphi3\Bin ディレクトリに置かれます)。

Miscrosoft Windows のタスクバーにある［スタート］メニューから［ファイル名を指定して実行(R)］を選び，DELPHI32.EXE へのパスを指定します。1060002

Delphi 開発環境にはいくつかの主なツールがあります。


Placing components on a form
Placing components on a form1060003

Section topics	参照

Delphi アプリケーションを構築するには，フォームにコンポーネントを追加してそのプロパティを設定し，イベントハンドラをコーディングします。

コンポーネントは，スクロールボックスやボタンなどのようにアプリケーションではビジュアルな部分ですが，データベースからの情報の取得，計算の実行，およびその他の相互作用の管理を行うコンポーネントは，UI ではビジュアルではありません。

コンポーネントパレットには，機能的にグループ化された多数のコンポーネントが用意されています。パレットに含まれていないコンポーネントは，Delphi ビジュアルコンポーネントライブラリから使用します。


Changing component appearance and behavior
Changing component appearance and behavior1060004

Section topics	参照

オブジェクトインスペクタを使うと，アプリケーションでのコンポーネントの外観と動作を簡単にカスタマイズできます。コンポーネントのフォーカスがフォームにあるとき，そのプロパティとイベントはオブジェクトインスペクタに表示されます。


Navigating among events
Navigating among events1060005

Section topics	参照

オブジェクトインスペクタの［イベント］タブをクリックして，各コンポーネントで扱えるイベント間を移動します。次の例では，Button2 が選択されたままで，その型 TButton が表示されています。

または，値列をダブルクリックします。Delphi はオブジェクトのデフォルトイベント用のスケルトンコードを生成して，コードの入力ができる状態にします。

フォームのオブジェクトをダブルクリックして，デフォルトイベント用のコードを生成することもできます。


Editing code with the Delphi Code editor
Editing code with the Delphi Code editor1060006

Section topics	参照

アプリケーションのユーザーインターフェースをビジュアルに設計するとき，Delphi は基礎を形成する Pascal コードを作成します。フォームとコンポーネントのプロパティを選択して変更すると，その変更結果が自動的にソースコードに表示され，その逆も行われます。

組み込みの Delphi コードエディタも含めたどのテキストエディタを使ってもソースファイルを変更できます。変更内容は，ビジュアル環境にすぐに反映されます。

コードエディタの中から Object Pascal の言語要素のヘルプを見るには，カーソルをその言語要素に置いて〔F1〕を押します。


The Code editor is completely customizable
The Code editor is completely customizable1060007

Section topics	参照

Delphi コードエディタは，完全機能のテキストエディタです。作業環境に合わせてさまざまにカスタマイズできます。

［色］ページでは，［文法要素(E)］から要素を選択し，その色を設定します。［表示］ページでは，フォントとその他のプロパティを設定します。


Debugging applications
Debugging applications1060008

Section topics	参照

Delphi では，アプリケーションのエラーの検出と修正を助ける統合デバッガが提供されています。デバッガを使うと，デバッグしながら，プログラムの実行のコントロール，データ構造のさまざまな値と項目の監視，およびデータ値の変更ができます。

デバッガの機能を使ってプログラムの現在の状態を検査できます。プログラムの特定の領域のデバッグ，1 度に 1 行または 1 命令の実行，ブレークポイントの設定，あるいは実行の一時停止ができます。変数の値，呼び出し履歴の関数，そしてプログラム出力を表示して，検査しているコードの領域が設計通りに実行されているかチェックできます。


Exploring databases
Exploring databases1060009

Section topics	参照

Database Explorer (または Delphi クライアント/サーバー版の SQL Explorer) により，アプリケーション開発中のリモートデータベースサーバーとの持続的な接続が維持できます。SQL Explorer では以下のことができます。

データベースエリアスの作成および維持

テーブル，ストアドプロシージャ，そしてトリガーのようなデータベースの概要データの表示

フィールドおよびインデックスのようなテーブルオブジェクトの表示

テーブル内のデータの作成，表示，変更

SQL 文を入力して，任意のデータベースに直接問い合わせる

データ辞書を作成，維持し，属性セットを格納する


Flexible tool for storing objects as templates
Flexible tool for storing objects as templates1060010

Section topics	参照

フォーム，データモジュール，エキスパート，および DLL のようなアプリケーションオブジェクトを Delphi のオブジェクトリポジトリに保管しておき，それらを簡単に再利用できます。あらかじめ多数のテンプレートがリポジトリに格納されています。

［ツール(T)｜リポジトリ］コマンドを使うと，オブジェクトリポジトリにオブジェクトを追加できます。保管されたオブジェクトは，［ファイル(F)｜新規作成(N)］コマンドで以下のような［新規項目］ダイアログボックスをオープンすると使用できます。

独自のページを追加するには，ダイアログボックスを右クリックして，メニューから［プロパティ(R)］を選択します。これにより［オブジェクトリポジトリ］ダイアログボックスが開きます。


Project file-management tool
Project file-management tool1060011

Section topics	参照

プロジェクトマネージャを使うと，フォーム，そして Delphi アプリケーションを作成しているファイル単位への追跡やアクセスが簡単にできます。［表示(V)｜プロジェクトマネージャ(P)］を選び，アプリケーションのファイルリストを表示すると，ファイル間を簡単に移動できます。

ユニットを表示するには，［ユニット］ボタンをクリックするか，［ユニット］列のユニット名をダブルクリックするか，目的のユニットを選択して〔Enter〕を押します。

フォームを表示するには，［フォーム］ボタンをクリックするか，［フォーム］列のフォーム名をダブルクリックするか，目的のフォームを選択して〔Shift〕+〔Enter〕を押します。


Handy pop-up menus
Handy pop-up menus1060012

Section topics	参照

オブジェクトおよびいくつかの Delphi ツールの上でマウスを右クリック (マウスの設定を変更している場合は左クリック) すると，状況に適したコマンドのメニューが表示されます。このようなメニューをスピードメニューと呼びます。

次の図では，パネルオブジェクトが選択されています。パネルオブジェクト上で右クリックするとメニューが表示されます。


Toolbar buttons for frequently used commands
Toolbar buttons for frequently used commands1060013

Section topics	参照

コンポーネントパレットの左側にある Delphi ツールバーつまりスピードバーには，一般的な操作やコマンドを実行するボタンが含まれています (ファイルのオープン，ファイルの保管，プロジェクトにファイルを追加など)。

ボタンの動作を確かめるには，マウスポインタをしばらくボタンの上に置いて，表示されるヒントを見ます。スピードバーを右クリックしてヒントの表示をオフに切り替えると，これらのヒントは表示されなくなります。メニューを右クリックして，スピードバー全体を非表示にすることもでき，これによってコンポーネントパレットにスペースができます。もう一度スピードバーを表示するには，［表示(V)｜スピードバー(S)］を選択します。


Getting help
Getting help1060014

Section topics	参照

Delphi のオンラインヘルプには，Delphi に付属するマニュアルと同じ内容およびその他の情報が含まれています。状況感知型のヘルプを表示するには，ダイアログボックス，ウィンドウ，またはコードエディタで〔F1〕を押します。


See also1060015

コンポーネントパレットについて

コンポーネントについて

コンポーネントのプロパティの設定

イベントハンドラでの作業

コードエディタの使い方

エディタのカスタマイズ

統合デバッガの使い方

SQL エクスプローラを使ったブラウズと設計

オブジェクトリポジトリのデータモジュールの再利用

プロジェクトの内容の表示と操作


First app--a brief tutorial
First app--a brief tutorial1077001

Section topics	参照

この章では，Delphi とともに提供される初期データベーステーブルのフィールドを操作するDelphi の小さなプログラムの作成過程を紹介します。まずデータベーステーブルへのアクセスを設定し，標準のファイル保存ダイアログボックスを表示するイベントハンドラを作成します。これによって，データベーステーブルの情報をファイルに書き込めるようになります。


Starting a new application
Starting a new application1077002

Section topics	参照

新規アプリケーションに取り掛かる前に，そのアプリケーションのソースファイルを格納するための独自のフォルダを作成しておきましょう。こうしておけば，アプリケーションのソースファイルと他の種類のファイルとが入り交じることがなくなります。また，独自のファイルを作成しておけば，アプリケーションに含まれるすべてのファイルの追跡と管理が簡単になります。

1.	この簡単なアプリケーションで作成するプロジェクトファイルを保存するために，作業ドライブのルートディレクトリに MySource というフォルダを作成します。

2.	新規プロジェクトを開きます。
Delphi では，アプリケーションのそれぞれをプロジェクトと呼びます。Delphi を起動すると，デフォルトで空白のプロジェクトが開きます。すでに別のプロジェクトを開いている場合には，［ファイル(F)｜アプリケーションの新規作成(T)］を選択すると新しいプロジェクトが作成されます。
新規プロジェクトを開くと，Delphi では，必ず以下の 2 つのファイルが自動的に作成されます。

UNIT1.PAS: メインプロジェクトフォームに関連するソースファイル

PROJECT1.DPR: プロジェクトに含まれるフォームを記憶するソースファイル

3.	［ファイル(F)｜すべて保存(V)］を選択して，プロジェクトファイルをディスクに保存します。［Unit1 に名前を付けて保存］ダイアログボックスが表示されたら，MySource フォルダに移り，2つの Delphi ファイルをデフォルトのファイル名で保存します (Delphi の名前を付けて保存ダイアログボックスを使い，新たに MySource ディレクトリに保存することもできます)。

この 2 つのファイルのほかに，Delphi はプロジェクトに関連する他のファイルも作成します。これらのファイルも MySource ディレクトリに保存されます (これらのファイルの詳細については，「プロジェクトとは」を参照してください)。

新規プロジェクトを開くと，Delphi ではデフォルトで Form1 という名前のフォームが表示されます。1077003

デフォルトの新規フォームには，最大化ボタン，最小化ボタン，［閉じる］ボタン，コントロールメニューがあります。ここで〔F9〕を押してフォームを実行すると，これらのボタンはすべて機能します。実行した後で設計モードに戻るにはフォームを閉じます。

Delphi では，フォームを使ってアプリケーションのユーザーインターフェースを設計します。フォームにはメニューとコンテキストメニューを含めることができます。また，フォームを組み合わせてアプリケーションのダイアログボックスを作成でき，フォーム自体が親ウィンドウにも子ウィンドウにもなれます。つまり，フォームとは，アプリケーションを作成するための土台です。

ユーザーインターフェースを作成するには，フォームにオブジェクトを配置します。オブジェクトには，標準インターフェースコントロール (たとえばチェックボックスやドロップダウンリスト) や，機能豊富なコンポーネント (たとえばデータグリッド，チャート，エディタなど) を選ぶことができます。

フォームの他に，Delphi にはオブジェクトインスペクタも表示されます。オブジェクトインスペクタは，実際にはユーザーアプリケーションのインターフェースの一部ではありませんが，プロジェクトに配置されたオブジェクトのすべての設計時設定を表示するツールです。

In the following figure, the drop-down list at the top of the Object Inspector shows the currently selected object; in this case, the object is Form1 and its type is TForm.1077004

プロジェクトのフォームにフォーカスがあるとき，オブジェクトインスペクタはここに示すようにフォームのプロパティを表示します。


Setting a property value at design time
Setting a property value at design time1077005

Section topics	参照

アプリケーションインターフェースの外観を設計するには，オブジェクトインスペクタを使ってオブジェクトプロパティの値を設定します。アプリケーションインターフェースを組み合わせながらオブジェクトインスペクタでプロパティ値を設定することを設計時設定を行うと言います。

Form1 の Color プロパティを clAqua に設定する

Color プロパティを設定するには，オブジェクトインスペクタでそのフォームの Color プロパティを探し，そのプロパティの右側に表示されているドロップダウンリストをクリックします。フォームの背景色を水色に変更するには，定義済みの色のリストから clAqua を選択します (図 3.2 を参照してください)。

メモ	プログラミング環境を使ってプログラムオブジェクトの値を初期化するという発想は，ほとんどのDelphi プログラマには馴染みがないかもしれません。アプリケーションのソースコードで直接にプロパティの初期値を設定したくなるかもしれませんが，Delphi でプログラムを作るときには，必ずオブジェクトインスペクタとそのプロパティエディタを使ってオブジェクトプロパティ値を初期化してください。こうすれば，Delphi がプログラムオブジェクトとソースコードの全体構造を設定し，管理できるようになるからです。


Adding objects to the form
Adding objects to the form1077006

Section topics	参照

Delphi のコンポーネントパレット (以下の図を参照) には，アプリケーションの作成に使用できるコンポーネントの大部分が一覧表示されています。アクセスしやすいように，コンポーネントはパレットのページ単位にグループ化されています。対応するコンポーネントパレットのタブをクリックすると，パレットのページをスクロールできます。

In the following figure, the SpeedBar has been hidden to allow more room for the palette:1077007

コンポーネントパレットのコンポーネントを利用すると，アプリケーションのインターフェースを手早く作成できます。

1.	コンポーネントパレットの［Standard］ページにある Panel コンポーネントをダブルクリックして，フォームに Panel コンポーネントを追加します。

Panel コンポーネントを見つけるには，コンポーネントパレットの適当なコンポーネントをしばらくポイントします。すると，図 3.4 のように，そのコンポーネントの名前を示すヘルプが表示されます。Panel コンポーネントが見つかったならば，ダブルクリックします。すると，現在のフォームの中央に Panel コンポーネントが追加されます。

Finding the Panel component1077008

フォームにコンポーネントを配置することで，そのコンポーネントのオブジェクトインスタンスが作成されます。これは，専門的な作業に見えるかもしれませんが，Delphi のコンポーネントとアプリケーションで使用するオブジェクトの違いを理解する上で役に立ちます。フォームにコンポーネントを配置すると，Delphi は，アプリケーションでそのオブジェクトを作成するのに必要な Pascal コードのすべてを作成します。ここに，Delphi の真価があります。アプリケーションで使用するオブジェクトの作成や管理を行うコードをユーザーが意識する必要はありません。Delphi がすべての作業を肩代わりします。

2.	Panel オブジェクトの Align プロパティに alBottom を設定します。
フォーム上の Panel オブジェクトにフォーカスをあてると，オブジェクトインスペクタでもこのオブジェクトにフォーカスが移ります。オブジェクトインスペクタで Align プロパティに alBottom を設定すると，このパネルがフォームの下端に沿って平らに延びるようになります。

3.	フォームの右下隅をドラッグして，アプリケーションウィンドウのサイズを拡大します。

4.	パネルをクリックして選択し，上の境界線を上にドラッグして，フォームの下 1/3 を占めるようにパネルのサイズを拡大します。フォームは図 3.5 のようになるはずです。

Form with a Panel object1077009

5.	フォームに Table オブジェクトを配置します。
コンポーネントパレットの［Data Access］タブをクリックして，このパレットページのコンポーネントにアクセスします。Table コンポーネントはこのページの左の方にあります。Table コンポーネントが見つかったら，1 回クリックして選択し，次にフォームをクリックして，このコンポーネントをフォームに配置します。
フォームにテーブルをドロップすると，そのオブジェクトのデフォルト名は Table1 になります。

6.	Table1 の DatabaseName プロパティに DBDEMOS を設定します (DBDEMOS はユーザーが使用するテーブルを含むデータベースの別名です)。DBDEMOS は，DatabaseName プロパティドロップダウンリストから選択できます。
このプロパティ値を設定すると，データベーステーブルへのアクセスが設定されます。


Accessing a database
Accessing a database1077010

Section topics	参照

これでデータベースコントロールのデータソースを設定する準備ができました。データソースを設定する手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページから DataSource コンポーネントをフォームに配置します。このコンポーネントの DataSet プロパティに Table1 を設定します。

2.	［Data Controls］ページの DBGrid コンポーネントをクリックして選択し， Panel1 の内側をクリックして，このコンポーネントをパネルに配置します。フォームは図 3.6 のようになります。

Form with a DBGrid object1077011

コンポーネントパレットの［Data Controls］ページには，アプリケーションでデータベースのデータを表示する方法を制御できるコンポーネントが含まれます。データベーステーブルの全項目を表示するには DBGrid コンポーネントを使います。

アプリケーションの実行中は，Table オブジェクトと DataSource オブジェクトは表示されません。

以下の DBGrid プロパティを設定して，グリッドの位置を合わせ，Table オブジェクトと DataSource オブジェクトで設定したデータベースにアクセスするようにします。

Align プロパティに alLeft を設定し，パネルの右側 3/4 を占めるように右の境界線をドラッグする

DataSource プロパティに DataSource1 を設定する

これで，フォームにドロップした Table1 オブジェクトの設定を完成させることができます。

3.	フォームで Table1 オブジェクトをクリックしてフォーカスをあて，以下のプロパティを設定します。

TableName に BIOLIFE.DB を設定する

Active に True を設定する

Active プロパティに True を設定すると，データベーステーブル BIOLIFE.DB に含まれるデータがグリッドに書き込まれます (グリッドが図 3.7 のようにならない場合には，ここまでの手順の説明どおりにすべてのアプリケーションオブジェクトのプロパティを正しく設定してあるかどうかを確認してください)。

Form with an Active Table11077012

DBGrid コントロールはデータベース対応ですから，アプリケーション設計中でもテーブルのデータを表示します。このデータ表示のおかげで，データベースに正しく接続されているかどうかを視覚的にチェックすることができます。ただし，データベース対応とはいっても，設計時にデータを編集できるというわけではありませんので注意してください。テーブルを編集するためには，アプリケーションを実行する必要があります。

4.	〔F9〕を押して，プロジェクトをコンパイルし実行します。


Adding some spice
Adding some spice1077013

Section topics	参照

アプリケーションを実行すると，フォーム上で設計したものと全く同じウィンドウの中に Delphi がプログラムを開きます。このプログラムは，最小化ボタン，最大化ボタン，そしてウィンドウの左上隅からアクセスできるコントロールメニューを含む完全な Windows プログラムです。データグリッドにはテーブルの値が書き込まれており，データグリッドをスクロールして BIOLIFE.DB テーブルのすべての値を見ることができます。

このプログラムにはこれらの要素がすべてが含まれていますが，まだ細部の詰めが不十分です。コントロールメニューをダブルクリックしてアプリケーションを閉じ，設計時のフォームの表示に戻ります。

1.	コンポーネントパレットの［Data Controls］ページから，次の図 3.8 のように DBNavigator オブジェクトをフォームにド配置します。

2.	その DataSource プロパティに DataSource1 を設定します。

Form1 with a DBNavigator object1077014

デフォルトの DBNavigator には簡単なアプリケーションに必要なもの以上のコントロールが含まれています。ここで必要なのは，［最初のレコード］，［前のレコード］，［次のレコード］，［最後のレコード］のナビゲータボタンだけです。どのナビゲータボタンを表示するかは，DBNavigator コントロールの VisibleButtons プロパティで指定します。

3.	DBNavigator にフォーカスをあてて，オブジェクトインスペクタのプロパティラベル VisibleButtons をダブルクリックします。
オブジェクトインスペクタに VisibleButtons の列挙リストが展開されます。展開された VisibleButtons プロパティのそれぞれが，DBNavigator の1つのボタンに対応します。これらのプロパティは，True または False に設定できる論理値を持ち，False の場合にはボタンが表示されなくなります。

4.	以下の VisibleButtons に False を設定します (これらのボタンプロパティをダブルクリックすると，値が True から False に切り替わります)。

nbInsert	nbDelete	nbEdit
nbPost	nbCancel	nbRefresh
5.	コンポーネントパレットの［Standard］ページから，もう 1 つの Panel コンポーネントをフォームの上にドロップします。Delphi は，このパネルに Panel2 というデフォルト名を付けます。実行中のアプリケーションからこのキャプションを取り除くには，このパネルの Caption プロパティから Panel2 という文字列を消去します。

6.	Panel2 の Align プロパティに alTop を設定して，このパネルをフォームの上部に位置合わせします。次に，Panel2 の下の境界線を下にドラッグして，フォームの上部をおおうようにします。

7.	2 つのパネルの Color プロパティに clBlue を設定します。
Delphi では，複数のコンポーネントのプロパティ値を同時に設定できるようになっています。まず Panel1 をクリックし，次に〔Shift〕を押したままで Panel2 をクリックします。オブジェクトインスペクタには，両方のコンポーネントに共通するプロパティがすべて表示されます。この状態から，両方のパネルの Color プロパティに clBlue を設定することができます。

8.	コンポーネントパレットの［Data Controls］ページから， DBImage コンポーネントをドラッグし，Panel2 の上にドロップします。このイメージの Align プロパティに alRight を設定し，イメージの左の境界線をドラッグして，図 3.9 のようになるまでサイズを変更します。

Form1 with a DBImage object1077015

ドラッグして DBImage の幅を設定できます。または，オブジェクトインスペクタで Width プロパティを設定します。

9.	DBImage の以下のプロパティを設定します。

DataSource に DataSource1 を設定する

DataField プロパティに Graphic を設定する (ドロップダウンリストに Biolife テーブルのフィールド名が表示されます。Graphic はフィールド名の 1 つです)

やはり，DBImage コンポーネントはデータベース対応ですから，テーブルの最初のレコードにある魚の絵がこのコンポーネントに表示されます。これによって，実際にそのデータベースに正しく接続していることがわかります。

10.	SpeedBar にある実行ボタン (矢印) をクリックして，アプリケーションをコンパイルし，実行します。


Final touches
Final touches1077016

Section topics	参照

ここでアプリケーションを実行すると，DBNavigator のボタンを使って，データベーステーブル内を簡単に移動できるようになっています。ところが，このアプリケーションをさらに役立つものにするために手を加えられる箇所がまだあります。実行中のアプリケーションを終了して，Delphi の設計モードに戻ってください。

1.	コンポーネントパレットの［Data Controls］ページから DBMemo コンポーネントをドラッグして Panel2 にドロップし，パネルの左上隅に配置します。次に以下のプロパティ値を設定します。

DataSource に DataSource1 を設定する

DataField に Notes を設定する (フィールドのドロップダウンリストを使う)

ScrollBars に ssVertical を設定する

2.	 Panel2 の DBMemo オブジェクトの下に DBText オブジェクトを配置します。DBText オブジェクトが DBMemo の下の領域いっぱいになるようにサイズを変更し，以下のプロパティを設定します。

DataSource に DataSource1 を設定する

DataField に Common_Name を設定する

3.	フォントエディタを使って，DBText オブジェクトの Font プロパティをカスタマイズします。

オブジェクトインスペクタからは，複数の異なる種類のプロパティエディタをアクセスできます。たとえばフォームメニューの編集にはメニューエディタ，ラベルフォントの編集にはフォントエディタ，ビットマップピクチャやグリフの編集にはピクチャエディタを利用することができます。

DBText オブジェクトの Font プロパティをクリックすると，プロパティ設定の右側に［...］ボタンが表示されます。これは，プロパティエディタを使ってこのプロパティを設定できることを表します。［...］ボタンをクリックすると，フォントエディタが表示され，そのダイアログボックスからフォントのいくつかの特性を編集することができます。

フォントエディタを使って，以下の DBText 設定を変更し，最後に［OK］ボタンをクリックします。

フォントスタイルにボールドを設定する

色に銀色を設定する

サイズを 12 に設定する


Adding an Exit button to your application
Adding an Exit button to your application1077017

Section topics	参照

このアプリケーションもいよいよ使えそうな雰囲気になってきました。ここで，さらにユーザーフレンドリーにするために，プログラムをワンタッチで閉じるための［Exit］ボタンを追加します。

1.	コンポーネントパネルの［Additional］ページから Panel1 に BitButton (BitBtn) コンポーネントをドロップし，その Kind プロパティに bkClose を設定します。

これによってボタンのデフォルト値が設定され，アプリケーション実行中にこのボタンをクリックすると，アプリケーションが閉じるようになります。

2.	BitButton の Caption プロパティを変更して，E&xit にします。

x の前にアンド記号があるので，この文字がショートカットキーになり，〔Alt〕+〔X〕を押すことでプログラムが終了できるようになります。

Your program should now look like this one:1077018

3.	〔F9〕を押して，アプリケーションをコンパイルし，実行します。

4.	［Exit］ボタンをクリックするか〔Alt〕+〔X〕を押してアプリケーションを終了します。


Hooking up an event handler
Hooking up an event handler1077019

Section topics	参照

ここで，完全に機能する Windows アプリケーションができあがりました。このアプリケーションは，データベーステーブルをアクセスし，データベースのイメージ，メモ，個々のデータフィールドを表示することができ，手際よくアプリケーションを終了するための［Exit］ボタンもあります。

しかし，今までのところプログラムコードは 1 行も入力していません。もちろん，Delphi 環境をフルに活用すればこうなるのです。オブジェクトインスペクタを利用してオブジェクトプロパティの設計時の値を設定することによって，Delphi が独自に生成するコードを Delphi そのものが管理できるようになるのです。言い換えると，プログラムにアプリケーションの作業を実行させるコードであるイベントハンドラを作成するという初期化の作業は Delphi にまかせて，人間がコーディングする手間を省いたのです。

次に人間が行わなければならないプログラミングは，ボタンにイベントハンドラをフックすることです。これは Delphi でユーザーインターフェースを設計するときに必要になることが多い作業です。ここでは，ボタンがクリックされたときに，イベントハンドラが Windows 標準のファイル保存ダイアログボックスを呼び出すようにプログラミングします。このダイアログボックスは，データベースから取り出した情報をファイルに保存するのに利用します。

1.	コンポーネントパレットの［Dialogs］ページから SaveDialog コンポーネントをクリックし，DataSource1 オブジェクトのとなりに配置します。

2.	コンポーネントパレットの［Additional］ページから BitButton (BitBtn) オブジェクトをドラッグし，［Exit］ボタンの上にドロップして，以下のプロパティを設定します。

Caption に &Save を設定する

［画像の設定］ダイアログを使って, Glyph に定義済みの FILESAVE.BMP ビットマップを設定する

Glyph プロパティをクリックすると，プロパティ設定の右側に［...］ボタンが表示されます。［...］ボタンをクリックすると［画像の設定］ダイアログが開きます。［画像の設定］ダイアログでは，［読み込み(L)］ボタンをクリックし，Delphi ディレクトリ階層内の次のフォルダへ移動します。

<Delphi メインディレクトリ>\Images\Buttons

このディレクトリから，グリフ FILESAVE.BMP を探して読み込みます。［画像の設定］ダイアログで［OK］を選択すると，このグリフが［Save］ボタンの左側に表示されるはずです。

これでアプリケーションのユーザーインターフェースが完成しました。この章の全ステップを実行すると，最終的な結果は図のフォームのようになるはずです。1077020

ここからが Delphi プログラミングのツボ，イベントハンドラの作成と記述です。イベントハンドラの作成は簡単ですが，実際にイベント用の Pascal コードを書くときにはテクニックが必要です。

3.	［Save］ボタンをダブルクリックして，ボタンのデフォルトイベントハンドラを作成します。
Delphi のフォームにあるオブジェクトをダブルクリックすると，そのオブジェクトのデフォルトイベントハンドラのコードが生成されます。また，編集ウィンドウが開かれ，begin..end の間の行の先頭にカーソルが移動します。この例の場合，Delphi は次のイベントハンドラコードを生成します。

procedure TForm1.BitBtn2Click(Sender: TObject);

begin

end;

end.

ここまでは，オブジェクトインスペクタは，オブジェクトのプロパティを設定するのに利用してきました。しかし，オブジェクトインスペクタは，オブジェクトのイベントハンドラをアクセスしたり生成するのにも利用できます。オブジェクトインスペクタの［イベント］タブをクリックすると，Delphi のフォームで現在フォーカスが当たっているオブジェクトの使用可能なイベントが表示されます。
コンポーネントパレットのほとんどのコンポーネントにデフォルトイベントがあります。フォーム上のオブジェクトをダブルクリックすると，デフォルトイベントのハンドラが作成されます。ほとんどのコンポーネントでは，OnClick がデフォルトイベントです。これは，実行中のアプリケーションのオブジェクトがクリックされたときに必ず呼び出されるイベントです。

4.	次のようにイベントハンドラを記述して，イベントハンドラを完成させます。

procedure TForm1.BitBtn2Click(Sender: TObject);

var

  i: integer;

begin

  SaveDialog1.Title :=Format('Save info for %s', [DBText1.Field.AsString]);

  if SaveDialog1.Execute then

  begin

    with TStringList.Create do

    try

      Add(Format('Facts on the %s', [DBText1.Field.AsString]));

      Add(#13#10);

      for i := 1 to DBGrid1.FieldCount-3 do

        Add(Format('%s : %s',

          [DBGrid1.Fields[i].FieldName,

           DBGrid.Fields[i].AsString]));

      Add(Format(CRLF+'%s'+CRLF,[DBMemo1.Text]));

      SaveToFile(SaveDialog1.FileName;

    finally

      Free;

    end;

  end;

end;

このコードの動作の詳細な説明は，この章の目的から外れています。ここでは，ユーザーが［Save］ボタンを押したときにこのコードがファイルを保存ダイアログボックス (SaveDialog1 オブジェクト) を呼び出す，と説明するだけにしておきます。このダイアログボックスでファイル名を指定すると，現在選択されている魚に関するデータがそのファイルに書き込まれます。

5.	完成したアプリケーションを実行するには〔F9〕を押します。

おめでとうございます。初めての Delphi アプリケーションが完成しました。

新しいプログラムをディスクに保存するには，［ファイル(F)｜プロジェクトに名前を付けて保存(E)］を選択します。Delphi のプロジェクトやプロジェクトファイルの命名規則についての詳細は「プロジェクトの使い方」を参照してください。


See also1077021

Jump in

コンポーネントについて

コンポーネントのプロパティの設定

フォームへのコンポーネントの追加

パネル

データソースの操作

テーブルの操作

グリッドの操作

データコントロールの使い方

項目コンポーネントの操作

データセットについて

ボタンおよび類似のコントロール

イベントハンドラでの作業


Working with projects
Working with projects1067001

Section topics	参照

Delphi で作業するときは，プロジェクトの作業が中心になります。この章では，Delphi プロジェクトを構成するファイルと，作業するときのプロジェクトの管理方法を取り上げます。この章では，以下のことについて説明します。

プロジェクトとは何か

プロジェクトの内容の表示と操作

プロジェクトコンポーネント間の移動

プロジェクト，および各プロジェクトファイルの保存

オブジェクトの共有

デフォルトプロジェクト，プロジェクトオプション，新規フォーム，メインフォームの設定

複数のバージョンの管理とチーム開発

プロジェクトのコンパイル，構築，実行


What is a project?
What is a project?1067002

Section topics	参照

Delphi プロジェクトとは，Delphi アプリケーションまたは DLL (ダイナミックリンクライブラリ) を構成するファイルの集合体です。プロジェクトファイルには，プロジェクトの設計時に生成されるものと，プロジェクトソースコードをコンパイルするときに作成されるものがあります。

プロジェクトを効果的に管理するには，Delphi プロジェクトを構成する各ファイルとファイルの種類を理解することが不可欠です。特別な場合を除いて，個々のファイルを処理する必要はほとんどありません。これらのファイルはどれもソースコードまたはスクリプトとして直接編集できますが，Delphi ではビジュアルツールを使った方が簡単で，しかも確実です。


Project file
Project file1067003

Section topics	参照

Delphi プロジェクトには，必ず Object Pascal ソースコードがあります。これは，完成したアプリケーションかダイナミックリンクライブラリにコンパイルされます。プロジェクトのソースコードで中心的なものをプロジェクトファイルといいます。プロジェクト開発の全体にわたって Delphi はこのファイルを更新します。

もっとも単純なプロジェクトはプロジェクトファイルだけで構成されます。しかし，複雑なプロジェクトでは，そのプロジェクトが使うすべてのフォームとユニットへの参照がプロジェクトファイルに入っています。プロジェクトを読み込み，保存，コンパイルすると，Delphi はプロジェクトファイルを調べてほかにどのファイルを使うか判断します。

デフォルトでは，Delphi プロジェクトファイルの拡張子は .DPR ですが，拡張子は特に重要ではありません。重要なのはファイルの内容だけです。ファイルの内容は，有効な Object Pascal コードでなければなりません。

プロジェクトをコンパイルまたは実行すると，実行形式ファイルまたはダイナミックリンクライブラリがコンパイラによってディスク上に作成されます。このファイルの名前はプロジェクトファイルと同じですが，拡張子はそれぞれ .EXE または .DLL です。

Inside the project file1067004

注意	プロジェクトファイルは Delphi が管理するので，通常は手作業で変更する必要はありません。一般的にはプロジェクトファイルの変更は薦められません。プロジェクトファイルの変更はプロジェクトマネージャでもできます。プロジェクトマネージャを使って変更すると，すべてのプロジェクト構成ファイルの同期を確実に保てます。

プロジェクトファイルを表示する主な理由は，プロジェクトを構成しているフォームやユニットを表示したり，どのフォームがアプリケーションのメインフォームとして指定されているか確認できるようにすることです。フォームやユニットをプロジェクトに追加したときに，Delphi がプロジェクトのソースコードをどのように更新するか確認できます。

プロジェクトファイルを開くには，次のいずれかの方法を使います。

［表示(V)｜プロジェクトソース(J)］を選択する

プロジェクトマネージャを右クリックして［プロジェクトソースの表示(P)］を選択する

プロジェクトファイルの内容はコードエディタのページに表示されます (プロジェクトファイルの表示を終了するには，コードエディタのページを閉じます)。

デフォルトの空白オブジェクトに対して以下のソースコードが生成されます。

program Project1;	{プロジェクト識別子を宣言する}

uses 	{プロジェクトが使うユニットを示す ...}

  Forms, 	{...フォームユニットを含み ...}

  Unit1 in 'UNIT1.PAS' {Form1};	{非フォームユニットと ...}

{$R *.RES}	{リソースファイルをリンクする}

begin	{メインプログラムブロックの始まり}

  Application.Initialize;

  Application.CreateForm(TForm1, Form1);	{最初のフォームの自動作成}

  Application.Run;	{アプリケーションを実行する}

end.	{メインプログラムブロックの終わり}

Project1 はプロジェクトの識別子である。Delphi ではこの識別子はプロジェクトファイルに名前を付けるときにも使われる。たとえば，プロジェクトソースコードファイルを MYNEWAPP.DPR という名前で保存すると，ソースコードの最初の行は次のようになる。

program MyNewApp;

予約語 program は，このプロジェクトがアプリケーションであることを示す。プロジェクトがダイナミックリンクライブラリ (DLL) の場合，かわりに予約語 library が表示される。

uses 節は，どのユニットをプロジェクトにリンクするかをコンパイラに示す。Forms は，フォームを使用するすべての Delphi プロジェクトが使う標準ユニットの識別子である

Unit1 は，フォームを 1 つ含む別のユニットの識別子である。UNIT1.PAS はユニットのソースコードを持つファイルの名前を表す。これらのファイル名は同じでなければならない。名前が異なると，プロジェクトは正しくコンパイルされない

予約語 in は，各ユニットのソースコードファイルの場所をコンパイラに知らせる。コメントの {Form1} は，このユニットに関連付けられたフォームのインスタンス識別子を表す (ただし，フォームに関連付けられていないユニットの場合，{Form1} は in 節には表示されない)。{Form1} はフォームの Name プロパティと同じである。オブジェクトインスペクタを使ってフォームに付けた名前は，プロジェクトファイル内に保持される

$R コンパイラ指令は，プロジェクトと同じ名前で拡張子 .RES の付いたファイルをプロジェクトにリンクすることを指定する。プロジェクトのリソースファイルには，プロジェクトのアイコンイメージなどが入る。詳細はオンラインヘルプで「リソースファイル指令」を参照

begin..end ブロックは，プロジェクトのメインソースコードブロックである

Application.CreateForm 文はこの文の引数に指定されたフォームをロードする。Delphi はプロジェクトに追加した各フォームについて，Application.CreateForm 文をプロジェクトファイルに追加する。追加された文は，プロジェクトにフォームが追加された順に並ぶ。この順序で，実行時にフォームがメモリに作成される。この順序を変更するには，プロジェクトソースコードを編集するのではなく，メニューコマンド［オプション(O)｜プロジェクト(P)］を使う (詳細は「プロジェクトオプションの設定」参照)

Application.Run 文はアプリケーションを実行する

プロジェクトに新しいフォームやユニットを追加するごとに，これらはプロジェクトソースコードファイルの uses 節に追加されます。詳細は「既存のフォームとユニットのプロジェクトへの追加」を参照してください。


Form files
Form files1067005

Section topics	参照

フォームは Delphi プロジェクトでもっとも目立つ部分です。Delphi 統合開発環境では，ビジュアルツールを使ってフォームを設計し，Delphi は設計したフォームのバイナリコードをフォームファイルに格納します。

フォームファイルをコードエディタで開くと，同じデータをテキストとして表示/変更できます。フォームファイルをテキスト表示に変換すると，保守とバージョン管理が簡単にできます。フォームのスピードメニューにある［テキストとして表示(V)］と［フォームとして表示(V)］，またはコードエディタを使うと，フォームとそのテキスト表示の切り替えが簡単にできます。

Delphi プロジェクトの各フォームにはユニットが関連付けられています。ユニットには，フォームまたはその中のコンポーネントのイベントに結び付けられたイベントハンドラのソースコードが入っています。フォームに関連付けられたユニットはフォームユニットともいいます。

フォームユニット，または保存してないフォームを持つプロジェクトを保存すると，各ユニットの名前の入力が求められます。入力した名前はユニットファイル名として使われ，拡張子 .PAS が付きます。これに対して，フォームファイルは同じ名前ですが拡張子は .DFM です。ユニットファイルにはどのような拡張子も使えますが，対応するフォームファイルではユニットファイルと同じ名前に拡張子 .DFM を付けてください。


Unit files
Unit files1067006

Section topics	参照

Delphi の Object Pascal 言語では，「ユニット」と呼ばれる個別にコンパイルしたコードモジュールを使うことができます。ユニットを使うと，複数のプロジェクト間で，構造化された再利用可能なコードを使えます。Delphi プロジェクトでもっとも頻繁に使うのはフォームユニットです。フォームユニットには，Delphi プロジェクトで使うフォームのイベントハンドラとその他のコードが入っています。ただし，ユニットはフォームに関連付ける必要はありません。ユニットをスタンドアロンのファイルとして作成して保存し，ほかのプロジェクトが使えるようにできます。たとえば，手続き，関数，DLL，コンポーネントを独自に作成し，フォームに関連付けられていない独立したユニットファイルにそのソースコードを保存できます。

新規デフォルトプロジェクトを開いて保存すると，プロジェクトディレクトリには最初にユニットソースコードファイル (UNIT1.PAS) とそれに関連付けられたフォームファイル (UNIT1.DFM) が 1 つずつ作成されます。

プロジェクトをコンパイルまたは実行するか，プロジェクトで構文チェックをすると，ユニットのソースコードから中間の出力ファイルがディスク上に作成されます。デフォルトでは，各ユニットをコンパイルしたものが，ユニットファイルと同じ名前で拡張子 .DCU が付いたバイナリファイル形式で格納されます。このようなバイナリファイルを開く必要はありません。また，完成したプロジェクトと一緒に配布する必要もありません。コンパイルしたユニット形式は Delphi コンパイラ独自のもので，コンパイルとリンクが短時間で行えます。

メモ	オプションとして，コンパイラで Intel の標準的なオブジェクトファイル (拡張子 .OBJ) を生成することもできます。この場合，ほかのコンパイラとの互換性が高まりますが，プロジェクトのコンパイルとリンクの速度は大幅に遅くなります。ただし最終的に生成されるコードの品質には影響しません。

Unit files for forms1067007

作業で使うほとんどのユニットファイルはフォームに関連付けられています。新しいフォームを作成すると，必ずそれに対応したユニットファイルが次のコードのように生成されます。デフォルトのユニット識別子は，新しいフォームを追加するたび Unit2，Unit3 などのように増加していきます。

unit Unit1;	{ユニット識別子}

interface

uses	{uses 節}

  SysUtils, Windows, Messages, Classes, Graphics, Controls,

  Forms, Dialogs;

type

  TForm1 = class(TForm)	{クラス宣言}

  private

    {Private 宣言}

  public

    {Public 宣言}

  end;

var

  Form1: TForm1;	{インスタンス宣言}

implementation

{$R *.DFM}	{フォームファイルをリンクするコンパイラ指令}

end.

type 宣言 (クラス宣言) 部では，フォームをクラスとして宣言します。クラスはオブジェクトです。Borland Pascal 製品のこれまでのバージョンやほかのオブジェクト指向プログラミング言語に詳しければ理解できるはずです。クラスとオブジェクトについての詳細は，「Delphi オブジェクトを使ったプログラミング」で解説します。

デフォルトの type 宣言では，新しいフォームは汎用フォームクラスである TForm の下位フォームになります。つまり新しいフォームには TForm オブジェクトのすべての動作と特性が備わっています。

var 宣言では，フォームを TForm1 クラスのインスタンスとして宣言します。

$R コンパイラ指令は TForm のバイナリフォームファイルをリンクします。つまり，プロジェクトのフォームファイルがコンパイル済みの実行形式ファイルに追加されます。

注意	フォームユニットフファイルから {$R *.DFM} 指令を削除しないでください。この指令を削除したコードは正しく動作しません。

Unit files for procedures and functions1067008

フォームに関連付けられたユニットに，独自の手続きや関数を入れることができます。しかし，作成した手続きや関数を再利用する場合は，再利用する手続きや関数だけが入ったユニットを別に作成する方が便利です。関連付けられたフォームがないスタンドアロンのユニットを作成すれば，特定の手続きや関数をほかのプロジェクトが簡単に使えるようにできます。

フォームに関連付けられていないユニットファイルを作成する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択します。

2.	［新規作成］ダイアログボックスから［ユニット］を選択します。

3.	［OK］を選択します。

新しいユニットをプロジェクトの一部にしない場合は，プロジェクトを開く必要はありません。

ユニットについての詳細は，「Object Pascal コードの書き方」を参照してください。『開発者ガイド』で解説するように，新規コンポーネントを作成するときにもユニットが使われます。


Resource files
Resource files1067009

Section topics	参照

Delphi では，標準の Windows 形式のリソースファイルを使って，アプリケーションアイコンなどの項目をプロジェクトに入れます。ビットマップ，カーソル，アイコン，文字列などのリソースをアプリケーションに追加するには，リソースファイルを編集するか独自にリソースファイルを作成します。

デフォルトでは，コンパイルしてアプリケーションにする各 Delphi プロジェクトごとに，プロジェクトファイルと同じ名前で拡張子 .RES が付いたリソースファイルがあります。


Package files
Package files1067010

Section topics	参照

プロジェクトではパッケージを選択して使うことができます。パッケージとは，Delphi で使用される特殊な DLL です。詳細は「パッケージの使い方」で解説しています。パッケージには .DPL (Delphi パッケージライブラリ) の拡張子が付き，パッケージソースファイルは .DPK (Delphi パッケージ) の拡張子が付きます。パッケージを含むプロジェクトを再構築すると，必要な場合にはパッケージは自動的に再コンパイルされます。


Other files
Other files1067011

Section topics	参照

Delphi では，プロジェクトの維持とコンパイルに関するほかのファイルも生成されます。このようなファイルは特に意識する必要はありませんが，以下のものがあります。

プロジェクトオプションファイル
プロジェクトオプション (コンパイラやリンカの設定，ディレクトリ，条件指令，コマンドラインパラメータなど) の現在の設定が入っているテキストファイルです。プロジェクトオプションは，メニューバーから［プロジェクト(P)｜オプション(O)］を選択して開く［プロジェクトオプション］ダイアログボックスで設定しますが，テキスト形式で保存されるため，保守，バージョン管理，共有が簡単にできます。
プロジェクトオプションファイルはプロジェクトファイルと同じ名前ですが，拡張子は .DOF です。

デスクトップ設定ファイル
このテキストファイルは，どのウィンドウが開いていてどの位置にあるかなどのプロジェクトの状態を示す情報を格納しています。これにより，プロジェクト単位で作業領域を復元できます。
デスクトップ設定ファイルはプロジェクトファイルと同じ名前ですが，拡張子は .DSK です。


Naming unit and project source code files
Naming unit and project source code files1067012

Section topics	参照

プロジェクトで開いた新しいユニットには，UNIT1.PAS，UNIT2.PAS，UNIT3.PAS などのデフォルト名が付けられますが，プロジェクトをデフォルト名だけで保存すると混乱が生じます。プロジェクトの各ユニットには，できるだけユニットの意味を表すような名前を付けて保存してください。プロジェクトファイルにすでに存在するユニットファイルの名前とは異なる名前にします。

ユニットファイルと同じように，プロジェクトファイルには PROJECT1.DPR というデフォルト名が付けられます。プロジェクトを初めて保存するときに具体的な名前を指定するようにしてください。

ユニットファイルとプロジェクトファイルの名前はどれも正当な Object Pascal 識別子でなければなりません。コンパイラはユニットファイルまたはプロジェクトファイルを探す場合，まずユニット識別子またはプロジェクト識別子の完全名を持つファイルを検索します。そのファイルが見つからない場合は，8 文字に切り捨てた識別子名を検索します。これは，下位互換性を保つほか，短いファイル名だけ格納するファイルサーバーとの互換性を保つためです。ファイル名は手作業で切り捨てて短くしないでください。


Storing a project
Storing a project1067013

Section topics	参照

プロジェクトはそれぞれ独自のディレクトリに保存する必要があります。プロジェクトはほとんどすべてのディレクトリにあるフォーム，ファイル，リソースを共有できますが，中心のプロジェクトファイルやそのプロジェクトに固有のほかのファイルは専用ディレクトリに保存しておくのが最良です。プロジェクトテンプレートやフォームの共有についての詳細は，「オブジェクトの共有」を参照してください。


Viewing and manipulating a project's contents
Viewing and manipulating a project's contents1067014

Section topics	参照

プロジェクトマネージャを使うと，現在開いているプロジェクトの状態やファイルの内容を表示できます。また，プロジェクトファイルのオープン，追加，保存，削除を行ったりするのに便利です (これらの作業は［ファイル(F)］メニューからも可能です)。プロジェクトマネージャを使えば，プロジェクトの構成ファイル間を簡単に移動したり，スピードバーとコンテキスト (右クリック) メニューによりプロジェクトオプションにアクセスしたりできます。

プロジェクトマネージャウィンドウを開く手順は次のとおりです。

1.	プロジェクトを開きます。

2.	［表示(V)｜プロジェクトマネージャ(P)］を選択します。

次の図は MDI アプリケーションのファイルを表示するプロジェクトマネージャです。［新規作成］ダイアログボックス (［ファイル(F)｜新規作成(N)］) の［プロジェクト］ページから開くことができます。また追加された共有ファイルも示しています。

The Project Manager1067015

ユニットを表示するには，［ユニット］をダブルクリックするか，選択してから〔Enter〕を押す。

フォームを表示するには，［フォーム］をダブルクリックするか，選択してから〔Shift〕+〔Enter〕を押す

プロジェクト間でファイルを共有している場合は，プロジェクトの各ファイルの格納場所を簡単に確認できるので，プロジェクトマネージャの使用をお薦めします。また，プロジェクトが使用するすべてのファイルを含むバックアップを作成するときには，特に便利です (バックアップ作成についての詳細は，「プロジェクト全体のバックアップの作成」を参照してください)。


Updating the Project Manager contents list
Updating the Project Manager contents list1067016

Section topics	参照

プロジェクトマネージャには現在のプロジェクトに関連付けられたすべてのファイルが表示されます。これらのファイルは .DPR ファイルの uses 節にリストが表示されます。このファイルを手作業で変更する (ソースコードを直接編集する) と，このリストに表示される情報は不正確になります。プロジェクトマネージャを開いたとき，Delphi はプロジェクトファイル内の情報と最後にプロジェクトマネージャに保存した情報を比較します。この情報が一致しないと，プロジェクトマネージャのファイルリストの内容は淡色表示になり，スピードバーの［更新］ボタンが使用可能になって，情報を一致させることができるようになります。

注意	Delphi にはプロジェクトを構成するファイルを常時監視し，プロジェクトファイルを自動的に更新する機能があります。このような機能とその波及効果を完全に理解していない限り，プロジェクトファイルを手作業で編集することは避けてください。プロジェクトファイルを編集すると，Delphi の自動化されたプロジェクト管理機能を使用しないことになり，プロジェクトコンポーネントに関する情報が不正確になる恐れがあります。その結果，コンパイルエラーなどの問題が発生することになります。


Getting project path and unit information
Getting project path and unit information1067017

Section topics	参照

［プロジェクトマネージャ］ウィンドウの一番下のステータスバーには，プロジェクトファイルのフルパス名とプロジェクト内のフォームとユニットの数が表示されます。

プロジェクトファイルのパス名は，メインプロジェクトディレクトリ以外の場所にある多数のフォームやユニットを現在のプロジェクトに取り込むときに役立ちます。フォームとユニットの数に関する情報は，プロジェクトを変更するときに変更の及ぶ範囲を判断するのに役立ちます。


Using Project Manager commands
Using Project Manager commands1067018

Section topics	参照

以下の表は，プロジェクトマネージャの［スピードバー］ボタン (と対応するメニューコマンド) の機能とその説明です。

ボタン	スピード メニューの コマンド	Delphi の メニューコマンド	機能	説明
追加	ファイルの追加(A)	ファイル(F)｜プロジェクトに追加(D)	共有ファイルや非共有ファイルをプロジェクトに追加する。共有ファイルの格納場所はプロジェクトマネージャの構成ファイルリストのパス名に反映される	非共有ファイルはプロジェクトディレクトリに格納されている。共有ファイルはプロジェクトディレクトリ外に格納されており，現在のプロジェクトディレクトリにコピーされることはない。どのプロジェクトで共有ファイルを変更しても，このファイルを使用するすべてのプロジェクトに変更が反映される
削除	ファイルの削除(R)	ファイル(F)｜プロジェクトから削除(J)	選択したファイルを現在のプロジェクトから削除する	選択したファイルと現在のプロジェクトの関係だけが削除される。ファイル自体は同じ場所に残る。プロジェクトファイルは変更を反映するように更新される
ユニット	ユニットの表示(U)	表示(V)｜ユニット(U) 〔Ctrl〕+〔F12〕	選択したファイルを (必要なら開いて) コードエディタに表示する。プロジェクトマネージャウィンドウで複数のファイルを選択している場合は，最後に選択したファイルを表示する	Delphi のメニューコマンドでは，［ユニットの表示］ダイアログボックスを開き，表示するユニットを指定できる
フォーム	フォームの表示(F)	表示(V)｜フォーム(F) 〔Shift〕+〔F12〕	現在選択されているフォームユニットのビジュアルイメージを表示する。現在選択されているファイルがフォームユニットでない場合は，このボタンとコンテクストメニューコマンドは使用不可になる	Delphi のメニューコマンドでは，［フォームの表示］ダイアログボックスを開き，表示するフォームを指定できる
オプション	オプション(O)	プロジェクト(P)｜オプション(O)	［プロジェクトオプション］ダイアログボックスを表示する
更新	更新(D)		プロジェクトマネージャウィンドウの表示をプロジェクトソースコード (.DPR) ファイルのリスト内容と一致させる	プロジェクト (.DPR) ファイルを手作業で変更していない限り，このボタンは使用不可となり，対応するスピードメニューコマンドも淡色表示になる。なお，手作業による変更は勧められない


Adding existing forms and units to a project
Adding existing forms and units to a project1067019

Section topics	参照

プロジェクトでは，現在のプロジェクトディレクトリやそのサブディレクトリには存在しない，別のプロジェクトで作成されたフォームファイルやユニットファイルも使用できます。これには，スタンドアロンのルーチンとして作成された Object Pascal のカスタム手続きや関数も含まれます。「プロジェクトマネージャのコマンドの使い方」の表は，プロジェクトマネージャを使ってこれらのファイルをどのようにプロジェクトに追加するかを示します。

プロジェクトをコンパイルする場合，プロジェクトを構成するファイルの格納元は，プロジェクトディレクトリ，そのサブディレクトリ，その他のどの場所でもかまいません。

プロジェクトに共有ファイルを追加する場合，このファイルが現在のプロジェクトディレクトリにコピーされるのではないことに留意してください。共有ファイルは現在の格納元に残ります。現在のプロジェクトに共有ファイルを追加するといっても，プロジェクトの .DPR ファイルの uses 節にファイル名とパスが登録されるだけです。Delphi では，プロジェクトにユニットを追加したときにこの登録が自動的に処理されます。コンパイラは，共有ファイルを現在のプロジェクトで作成したファイルと同様に扱います。

Using Borland Pascal source code units1067020

Borland Pascal または Turbo Pascal で記述したカスタム手続きやカスタム関数の既存のソースコードユニットがあれば，そのユニットを Delphi プロジェクトで使用することができます。これらのファイルを追加する方法は，Delphi で作成したファイルを追加する方法と同じです。


Removing forms and units from a project
Removing forms and units from a project1067021

Section topics	参照

プロジェクトの開発中は，いつでもプロジェクトからフォームやユニットを削除できます。削除するには，.DPR ファイルの uses 節からそのファイルへの参照を削除します。「プロジェクトマネージャのコマンドの使い方」の表に示した手順を使ってフォームと関連付けられたユニットを削除すると，フォームもプロジェクトから削除されます。

プロジェクトからファイルを削除すると，ファイルとプロジェクトが切り離されますが，ディスク上のファイルが削除されるわけではありません。

注意	Windows のファイル管理プログラムを使って Delphi プロジェクトファイルをディスクから削除するときは，その前に削除するファイルを使用しているすべてのプロジェクトで前述の削除作業を行ってください。そうしないと，削除したファイルを使用する各プロジェクトのプロジェクトファイルには，これらのファイルへの参照が残ります。そのため，プロジェクトを再び開くと Delphi は削除したファイルを探し，見つからないファイルごとにエラーメッセージを表示します。この場合，プロジェクトは開けますが，プロジェクトマネージャの構成ファイルに関する情報は不正確になります。


Using the Project Manager context menu
Using the Project Manager context menu1067022

Section topics	参照

以下に示すスピードメニューを使うには，プロジェクトマネージャで右クリックします。

メニューコマンドを強調表示して〔F1〕を押すと，そのコマンドに関する情報が表示されます。

開いているプロジェクトで［ユニットの新規作成(N)］コマンドを使用してユニットを作成すると，この新しいユニットは .DPR ファイルの uses 節に追加されます。［フォームの新規作成］コマンドを使用してフォームを作成すると，空白のフォームと新しいユニットがプロジェクトと .DPR ファイルの uses 節に追加されます。


Navigating among project components
Navigating among project components1067023

Section topics	参照

プロジェクトで作業していると，フォーム，ユニット，各種の開いたウィンドウ (プロジェクトマネージャや位置合わせパレットなど) の間を頻繁に移動しなければなりません。


Toggling between form image and unit source code
Toggling between form image and unit source code1067024

Section topics	参照

現在のフォームとそのユニットソースコードの間で表示を切り替えるには，以下の方法があります。

〔F12〕を押す

［表示(V)｜フォーム/ユニット切り替え(G)］を選択する

Delphi スピードバーの［フォーム/ユニット切り替え］ボタンをクリックする

プロジェクトマネージャで，ユニットの列をダブルクリックしてソースコードを表示するか，フォームの列をダブルクリックしてフォームイメージを表示する


Bringing a window to the front
Bringing a window to the front1067025

Section topics	参照

複数のウィンドウを開いている場合，ウィンドウを前面に表示する手順は次のとおりです。

1.	メニューで［表示(V)｜ウィンドウの一覧(I)］を選択するか，〔Alt〕+〔0〕(ゼロ) キーを押します。

2.	前面に表示するウィンドウの名前をダブルクリックします。

［ウィンドウの一覧］ダイアログボックス

Viewing forms and units1067026

フォームの一覧やユニットだけを見るためには［表示(V)｜フォーム(F)］または［表示(V)｜ユニット(U)］を選択します。画面のダイアログボックスからフォームまたはユニットを選択し，さらに［OK］を選択します。


Saving projects and individual project files
Saving projects and individual project files1067027

Section topics	参照

プロジェクト開発中は，開いているプロジェクトを現状のままでプロジェクトディレクトリにいつでも保存できます。プロジェクトのコピーに同じ名前または別の名前を付けてほかのディレクトリに保存することもできます。

また，プロジェクトをプロジェクトテンプレートとして保存し，自分やほかのユーザーが再利用できるようにオブジェクトリポジトリに追加することもできます。詳細は「プロジェクトをオブジェクトリポジトリへ追加する」を参照してください。

Delphi ではプロジェクト全体を保存できるだけでなく，プロジェクト内の個々の構成ファイルも保存できます。ファイルのコピーを別名でほかのディレクトリに保存することもできます。


Saving a project
Saving a project1067028

Section topics	参照

メモ	プロジェクトテンプレートからプロジェクトを作成した場合は，オブジェクトリポジトリでの選択操作でプロジェクトディレクトリが作成されます。プロジェクトテンプレートからプロジェクトを作成しなかった場合は，特に指定しない限り，プロジェクトは BIN ディレクトリに保存されます。

すべての開いているファイルをプロジェクトディレクトリに保存するには，以下の方法があります。

Delphi のメニューバーで［ファイル(F)｜すべて保存(V)］を選択する

Delphi のスピードバーで［すべて保存］ボタンを選択する

プロジェクトマネージャで右クリックし，コンテキストメニューで［プロジェクトを保存(S)］を選択する

この後プロジェクトを実際に保存する方法は，プロジェクトを前に保存したことがあるかどうかで多少異なります。

まだ 1 度も保存したことがないプロジェクトでは，［名前を付けて保存］ダイアログボックスが表示されます。このダイアログボックスでは，現在のプロジェクトで作成したすべての開いているユニットファイルに名前を付けることを求められます。ただし，プロジェクトに追加した共有ファイルは除きます。「オブジェクトの共有」を参照してください。
ユニットファイルに名前を指定すると，次は，プロジェクトファイルをディスクに保存する前に，それに名前を付けることを求められます。このような順序になっているのは，指定したユニットファイル名とフォームファイル名をプロジェクトファイルのソースコードに正しく登録するためです。

以前に保存したことのあるプロジェクトの場合，プロジェクトディレクトリに存在するすべての開いているファイルのうち，変更されたファイルがディスクに保存されます。
直前の保存より後にプロジェクトで新しいフォームやユニットを開いた場合は，［< ユニット名 > に名前を付けて保存］ダイアログボックスが表示されます。このダイアログボックスでは，ユニットファイルを保存する前に名前を指定することを求められます。
プロジェクトファイルは更新されて，プロジェクトに指定した新しいユニットや新しく共有したファイルを反映します。


Saving a copy of the project
Saving a copy of the project1067029

Section topics	参照

Delphi では，開いているプロジェクトの別のバージョンをプロジェクトディレクトリとは異なるディレクトリに保存できます。この保存は［ファイル(F)｜プロジェクトに名前を付けて保存(E)］コマンドで行います。ただしプロジェクトによっては，そのプロジェクトの一部として作成されたファイルのほかに，共有ファイルも使用している場合があります。そのため，［プロジェクトに名前を付けて保存(E)］で新しい場所に保存されるのは，プロジェクトファイル，プロジェクトオプション設定ファイル，プロジェクトリソースファイルの各コピーだけです。

重要	ユニットファイルは新しい場所には保存されません。コピーしたバージョンを開くと，プロジェクトマネージャは，コピーしたプロジェクト内のすべてのユニットを共有ファイルとして表示します。つまり，新しいプロジェクトディレクトリに格納されているユニットファイルはありません。

プロジェクトファイルのコピーを別の場所に保存する手順は次のとおりです。

1.	Delphi のメニューバーで［ファイル(F)｜プロジェクトに名前を付けて保存(E)］を選択して［<プロジェクト名> に名前を付けて保存］ダイアログボックスを表示します。

2.	プロジェクトファイルをコピーする先のディレクトリを選択します。

3.	プロジェクトファイルをほかの名前で保存する場合は，その名前を［ファイル名(N)］編集ボックスに入力します。指定したディレクトリ内に同じ名前のプロジェクトファイルが存在する場合は，既存のファイルを上書きするかどうか尋ねられます。

4.	［OK］を選択します。
開いているプロジェクトは，今保存したばかりのプロジェクトになっています。

Delphi はプロジェクトファイル，プロジェクトオプションファイル，プロジェクトリソースファイルを，新しい名前で新しい場所に保存します。また，元の場所にある変更されたユニットファイルも現在の場所に保存します。したがって，プロジェクトを終了するときに再び変更の保存を求められることはありません。なお，［プロジェクトに名前を付けて保存(E)］の操作で保存したすべての変更は，プロジェクトのどちらのバージョンにも反映されます。

プロジェクトマネージャでファイルリストを調べると，現在開いているプロジェクトのどのファイルも現在のプロジェクトディレクトリに存在せず，異なるディレクトリに存在することがわかります。各ファイルのコピーを新しいプロジェクトディレクトリにも保存する場合は，［ファイル(F)｜名前を付けて保存(A)］で各ファイルを別個に保存します (詳細は「プロジェクト全体のバックアップの作成」を参照)。

新しいプロジェクトを変更しない限り，このプロジェクトでは現在の場所 (つまり元の場所) にあるファイルを共有ファイルとして使用し続けます。このことは都合のよい場合も悪い場合もあります。新しいプロジェクトがどのようにファイルを使用しているかについて理解していないと，後で問題を生じる恐れがあります。

注意	プロジェクトのコピーを新しい場所に保存するには，Delphi の提供するファイル管理ツールだけを使用してください。


Saving individual files
Saving individual files1067030

Section topics	参照

プロジェクトの個々のファイルやコードエディタで開いたテキストファイルなどの非プロジェクトファイルも保存できます。なお，ファイルを保存するには，そのファイルを開いておきます。

個々のファイルを保存する手順は次のとおりです。

1.	ファイルのタブを選択してファイルをコードエディタの前面に表示します。

2.	［ファイル(F)｜上書き保存(S)］を選択します。これが最初の保存であればファイルに名前を指定することを求められます。

3.	必要に応じてファイルに名前を指定し，［OK］を選択します。
これでファイルは保存されます。

メモ	各ファイルは，その拡張子がそれぞれ違っていても固有の接頭語を指定する必要があります。たとえば，フォームとプロジェクトファイルの両方に［About］をファイル名として指定すると，次のようなエラーメッセージが表示されます。

このプロジェクトには About という名前のモジュールが既にあります。

このようなエラーメッセージが表示された場合，プロジェクトファイル (2 番目に名前指定したどのファイルも) は保存されません。別の名前を使ってファイルを保存します。

ファイルを別の名前で保存したり，別の場所に保存する手順は次のとおりです。

1.	ファイルのタブを選択してファイルをコードエディタの最前面に表示します。

2.	［ファイル(F)｜名前を付けて保存(A)］を選択します。
［名前を付けて保存］ダイアログボックスが表示されます。

3.	新しいファイル名と場所の両方または一方を指定して［OK］を選択します。
ファイルが指定の名前で指定の場所に保存されます。

メモ	保存したファイルは新しい名前に変わります。このファイルがすでにプロジェクトの一部になっている場合は，プロジェクトにおける名前も新しい名前に変わります。古いファイルは残りますが，プロジェクトからは切り離されます。


Creating a backup of an entire project
Creating a backup of an entire project1067031

Section topics	参照

プロジェクトのバックアップを作成するには，ディレクトリをコピーするだけで済む場合もありますが，ほかの作業を必要とする場合もあります。作業の複雑さは，プロジェクトディレクトリの構成内容と，プロジェクトで専用のディレクトリツリーに属さないファイルを使用しているかどうかによります。

プロジェクトファイルは，プロジェクトディレクトリ自体の場所は記録していませんが，プロジェクト内のほかのすべてのファイルの場所は記録しています。これらのファイルをメインプロジェクトディレクトリのサブディレクトリに格納していれば，すべてのパス情報は相対位置で示されるので，バックアップを作成するのは簡単です。このようなプロジェクトは，ディレクトリツリーを別の場所にコピーするだけでバックアップを取ることができます。バックアップの格納場所でプロジェクトを開けば，オリジナルの構造内にあるすべてのプロジェクトファイルがバックアップにも存在し，プロジェクトもコンパイルできます。

このディレクトリツリーに属さないファイルをプロジェクトで使用している場合，プロジェクトはバックアップ先でコンパイルできる場合もできない場合もあります。これらの外部ファイルがバックアップの格納場所からアクセスできるかどうか，プロジェクトマネージャのファイルリストで調べてください。ファイルへアクセスできれば，プロジェクトはコンパイルできます。ほかのバックアップ操作でこれらの外部ファイルをすでに保存している場合は，別個のバックアップコピーをバックアッププロジェクトディレクトリに作成する必要はありません。


Sharing objects
Sharing objects1067032

Section topics	参照

Delphi のオブジェクトリポジトリは，プロジェクト間でフォーム，ダイアログボックス，データモジュールを共有 (コピー) するための多彩な機構です。同一のプロジェクト内で似たようなフォームを再利用するのに使えるほか，新規プロジェクトの土台となるプロジェクトテンプレートの役目も果たします。オブジェクトリポジトリに追加したフォーム，ダイアログボックス，データモジュールは，ほかのプロジェクトでも使えます。実際，プロジェクト全体を今後のプロジェクトのテンプレートとしてオブジェクトリポジトリに追加することもできます。

オブジェクトリポジトリにはウィザードも入っています。ウィザードは，一連のダイアログボックスを使ってフォームまたはプロジェクトを作成するための小型アプリケーションです。Delphi には多数のウィザードが用意されていますが，開発者が独自に作成することもできます。

実際には，リポジトリは DELPHI 3\BIN ディレクトリの DELPHI32.DRO (Delphi リポジトリオブジェクト) という名前のテキストファイルです。このファイルには，［ツール(T)｜リポジトリ(R)］で開かれる［オブジェクトリポジトリ］ダイアログボックスと［ファイル(F)｜新規作成(N)］で開かれる［新規作成］ダイアログボックスに表示される項目への参照が含まれ，どのテキストエディタからでも開くことができます。


Sharing items within a project
Sharing items within a project1067033

Section topics	参照

オブジェクトリポジトリに追加せずにプロジェクト内で項目を簡単に共有できます。［新規作成］ダイアログボックスを開くと，プロジェクト名が付いたページタブが表示されます。このページタブをクリックすると，プロジェクト内のすべてのフォーム，ダイアログボックス，データモジュールが表示されます。既存の項目から新しい項目を派生させて，必要に応じてカスタマイズできます。


Sharing objects in a team environment
Sharing objects in a team environment1067034

Section topics	参照

チーム環境でオブジェクトを共有するには，チームメンバーが使用できるディレクトリを指定しておく必要があります。その後，オブジェクトリポジトリに項目を追加するとすぐ，指定したディレクトリに DELPHI32.DRO ファイルが作成されます。新しい DELPHI32.DRO ファイルには共有したいオブジェクトのポインタが含まれています。

共有するリポジトリのディレクトリを指定する手順は次のとおりです。

1.	［ツール(T)｜環境オプション(O)］を選択します。

2.	［設定］ページの［共有リポジトリ］パネルにある［ディレクトリ］編集ボックスに，共有するリポジトリを置きたいディレクトリ名を入力します。

共有するディレクトリの場所は Windows レジストリに格納されます。［環境オプション］ダイアログボックスで場所を変更すると，レジストリ内の場所も変更されます。

チームメンバー間でオブジェクトリポジトリの項目を共有するには，すべてのメンバーの［環境オプション］ダイアログボックスでのディレクトリの設定が同一の場所を指定していなければなりません。


Copy, Inherit, or Use?
Copy, Inherit, or Use?1067035

Section topics	参照

オブジェクトリポジトリの項目にアクセスするには，［ファイル(F)｜新規作成(N)］を選択します。［新規作成］ダイアログボックスが表示され，オブジェクトリポジトリのすべての項目が表示されます。プロジェクトに項目を追加するには，以下の 3 つの方法があります。

項目のコピー

項目の継承

項目の直接使用

The Copy option1067036

コピーを選択すると，項目とまったく同じものが複製され，プロジェクトにそのコピーが追加されます。オブジェクトリポジトリの項目を後で変更してもコピーには反映されず，コピーを変更しても元のオブジェクトリポジトリの項目には反映されません。

コピーは，プロジェクトテンプレートを使用できる唯一の方法です。

The Inherit option1067037

継承を選択すると，オブジェクトリポジトリで選択したその項目から新しいクラスが派生し，派生した新しいクラスがプロジェクトに追加されます。継承オプションを使うとリポジトリの上位項目に対するリンクが生成されます。プロジェクトを再コンパイルした場合，オブジェクトリポジトリの項目に対して行った変更は派生クラスにも反映されます。このような変更はプロジェクトの項目への変更や追加に加えて適用されます。派生クラスに対して行った変更はオブジェクトリポジトリの共有項目には反映されません。

フォーム，ダイアログボックス，データモジュールでは継承が使えますが，プロジェクトテンプレートでは使えません。また，同一プロジェクト内の項目を再利用する場合には，継承だけが行えます。

The Use option1067038

選択した項目をプロジェクトの一部にしたい場合は，直接使用を選択します。この場合，項目のコピーを作成するのではなく，選択しているオブジェクトをプロジェクトに追加します。項目の直接使用は，継承の逆のようなものです。項目にほかに加えられた変更を継承するのではなく，リポジトリの項目を使用するときに変更を継承します。項目への変更は，継承や直接使用オプションを選択して項目を追加したすべてのプロジェクトに反映されます。

注意	フォーム，ダイアログボックス，データモジュールについては直接使用だけしか行えませんが，使用に際しては注意が必要です。項目に対して行った変更は，リポジトリからアプリケーションにコピーする前に十分にテストしてください。

メモ	フォームエキスパートやプロジェクトエキスパートなどのエキスパートではこのオプションしか使えません。エキスパートを使うと，実際に共有コードが追加されるのではなく，固有のコードを生成するプロセスが実行されます。


Using project templates
Using project templates1067039

Section topics	参照

Delphi のプロジェクトテンプレートを使うと，設計済みのプロジェクトをプロジェクトの土台として使えます。

プロジェクトテンプレートを使って新規プロジェクトを始める手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［プロジェクト］タブを選択します。

3.	希望するプロジェクトテンプレートを指定して［OK］を選択します。

4.	［ディレクトリの選択］ダイアログボックスで新規プロジェクトファイル用のディレクトリを指定します。存在しないディレトリトを指定すると，Delphi がディレクトリを作成します。

テンプレートファイルはプロジェクトディレクトリにコピーされます。このプロジェクトは，新しいフォームやユニットに追加して変更することも，イベントハンドラコードだけを追加して変更せずそのまま使用することもできます。どちらの場合でも，変更は開いているそのプロジェクトだけに影響します。元のプロジェクトテンプレートは影響を受けないので再利用できます。


Adding items to the Object Repository
Adding items to the Object Repository1067040

Section topics	参照

独自に作成したプロジェクトやフォームデータモジュールを，オブジェクトリポジトリに追加することもできます。

オブジェクトリポジトリに項目を追加する手順は次のとおりです。

1.	項目がプロジェクトの場合またはプロジェクト内にある場合は，［表示(V)｜プロジェクトマネージャ(P)］で［プロジェクトマネージャ］ウィンドウを開きます。

2.	プロジェクトの場合は，［プロジェクト(P)｜プロジェクトをリポジトリに追加(T)］を選択します。フォームやデータモジュールの場合は，項目を右クリックするかスピードメニューから［リポジトリに追加］を選択します。

3.	［コメント(D)］，［タイトル(T)］，［作成者(A)］を入力します。

4.	［新規作成］ダイアログボックスでこの項目を表示したいページを［ページ(P)］コンボボックスで選びます。または，ページの名前を入力します。
入力したページ名が存在しない場合は，新しいページが作成されます。

5.	［参照(B)］を選んでアイコンを選択すると，オブジェクトリポジトリで表示されるアイコンイメージを選択することができます。

6.	［OK］を選択します。
これで，作成した項目が［オブジェクトリポジトリ］ウィンドウと［新規作成］ダイアログボックスに表示されるようになります。


Modifying a shared form
Modifying a shared form1067041

Section topics	参照

オブジェクトリポジトリ内の同一のフォームを複数のプロジェクトが共有している場合，フォームに対して行った変更は，フォームが各プロジェクトにどのようにインポートされているかによって，すべてのプロジェクトに影響します。プロジェクトがオブジェクトリポジトリからフォームをコピーしている場合は，オブジェクトリポジトリのフォームに後で変更を加えても，他のプロジェクトには影響しません。プロジェクトがオブジェクトリポジトリからフォームを継承している場合は，プロジェクトがコンパイルされるごとにオブジェクトリポジトリからフォームの最新バージョンを継承します。これにはプロジェクトが最後にコンパイルしてから加えられた変更も含まれます。プロジェクトがオブジェクトリポジトリからフォームを「直接使用」している場合は，プロジェクト内でフォームを変更すると，その変更はほかのアプリケーションがコピーしたり継承したりできるオブジェクトリポジトリ内の場所に直接保存されます。

ほかのプロジェクトがオブジェクトリポジトリからフォームを継承することがわかっていて，これらのプロジェクトが変更を複製するのを望まない場合，継承を防ぐいくつかの方法があります。

フォームを別の名前で保存し，名前を変更したフォームをプロジェクトで使う

設計時ではなく実行時にフォームを変更する

共有フォームをコンポーネントパレットにインストールできるコンポーネントにする
この方法には，ユーザーが設計時にフォームをカスタマイズできる利点もあります。詳細は，「コンポーネントテンプレートの作成」を参照してください。

フォームを使うのが自分だけであり，大幅にまたは頻繁に変更する予定がない場合は，実行時にカスタマイズする方法も有効です。しかし，複数の異なるアプリケーションでフォームを使う場合は，実行時にカスタマイズすると自分だけでなくほかの開発者も余分なコードを作成しなければならなくなります。その場合，可能な限りフォームをほかのユーザーまたは開発者のコンポーネントパレットにインストールできるコンポーネントにした方が便利です。

メモ	フォームを DLL の形に作成して再利用もできます。


Specifying a default project, new form, and main form
Specifying a default project, new form, and main form1067042

Section topics	参照

新規プロジェクト，新規フォーム，メインフォームにはデフォルトを指定できます。［ファイル(F)｜新規作成(N)］を選び［新規作成］ダイアログボックスからオプションを選択すると，いつでもデフォルトを変更できます。


Specifying the default new project
Specifying the default new project1067043

Section topics	参照

メニューバーで［ファイル(F)｜アプリケーションの新規作成(T)］を選択すると，デフォルトの新規プロジェクトが開きます。デフォルトのプロジェクトを指定しないと，Delphi は空白フォームの空白プロジェクトを作成します。デフォルトの新規プロジェクトとして，独自に作成してテンプレートとして保存したプロジェクトなども指定できます。

新規プロジェクトを開始するときにデフォルトでプロジェクトエキスパートを実行するように指定することもできます。プロジェクトエキスパートは，一連のダイアログボックスへ与えた情報に基づいてプロジェクトを構築するプログラムです。

デフォルトの新規プロジェクトを指定する手順は次のとおりです。

1.	［ツール(T)｜リポジトリ(R)］を選択して［オブジェクトリポジトリ］ダイアログボックスを開きます。

2.	［ページ(P)］リストから［プロジェクト］を選択します。

3.	［オブジェクト(O)］リストからデフォルトの新規プロジェクトにするプロジェクトを選択します。

4.	選択したプロジェクトで，［プロジェクトの新規作成時に使用］チェックボックスにチェックマークを付けます。

5.	［OK］を選択して，新しいデフォルトの設定を登録します。


Specifying the default new form
Specifying the default new form1067044

Section topics	参照

［ファイル(F)｜フォームの新規作成(F)］を選択したり，開いたプロジェクトにプロジェクトマネージャを使って新しいフォームを追加すると，デフォルトの新規フォームが開きます。デフォルトのフォームを指定しないと，Delphi は空白のフォームを使用します。デフォルトの新規フォームとして，どんなフォームも指定できます。また，新規フォームをプロジェクトに追加したときにデフォルトでフォームエキスパートを実行するようにも指定できます。

新規プロジェクトにデフォルトの新規フォームを指定する手順は次のとおりです。

1.	［ツール(T)｜リポジトリ(R)］を選択して［オブジェクトリポジトリ］ダイアログボックスを開きます。

2.	［ページ(P)］リストから［フォーム］を選択します。

3.	［オブジェクト(O)］リストからデフォルトの新規フォームに指定するオブジェクトを選択します。

4.	選択したオブジェクトで，［フォームの新規作成時に使用(N)］にチェックマークを付けます。

5.	［OK］を選択して，新しいデフォルトの設定を登録します。


Specifying the default main form
Specifying the default main form1067045

Section topics	参照

プロジェクトに新規フォームを追加するときに使うフォームテンプレートまたはフォームエキスパートを指定できるように，新規プロジェクトを開始するときにデフォルトのメインフォームとして使うフォームテンプレートまたはフォームエキスパートも指定できます。

プロジェクトのデフォルトのメインフォームを指定する手順は次のとおりです。

1.	［ツール(T)｜リポジトリ(R)］を選択して［オブジェクトリポジトリ］ダイアログボックスを表示します。

2.	［ページ(P)］リストから［フォーム］を選択します。

3.	［オブジェクト(O)］リストからデフォルトのメインフォームに指定するオブジェクトを選択します。

4.	選択したフォームで，［メインフォームとして使用(M)］にチェックマークを付けます。

5.	［OK］を選択して，新しいデフォルトの設定を登録します。


Setting project options
Setting project options1067046

Section topics	参照

［プロジェクトオプション］ダイアログボックスでプロジェクトの設定を変更できます。［プロジェクトオプション］ダイアログボックスを開くには以下の方法があります。

［プロジェクト(P)｜オプション(O)］を選択する

プロジェクトマネージャのスピードバーで［オプション］ボタンを選択するか，プロジェクトマネージャで右クリックしてコンテキストメニューから［オプション(O)］を選択する

デフォルトのチェックボックスにチェックマークを付ける (次節参照) 場合を除いて，変更した設定は，現在開いているプロジェクトだけに影響します。いずれかのデフォルトの設定を変更すると，次にプロジェクトを保存したときに，ファイル拡張子 .DOF が付いたオプションファイルがプロジェクトディレクトリに作成されます。従って，このプロジェクトオプションは，以降の作業セッションでプロジェクトを再度開いたときに有効になります。

以降の節では，プロジェクト管理に関連する［プロジェクトオプション］ダイアログボックスのオプションについて説明します。このダイアログボックスの各ページのオプションについての詳細は，各ページで［ヘルプ］ボタンをクリックしてください。


Setting options that affect all new projects
Setting options that affect all new projects1067047

Section topics	参照

［プロジェクトオプション］ダイアログボックスには，［デフォルト］というラベルの付いたチェックボックスがあります。このコントロールにチェックマークを付けると，［プロジェクトオプション］ダイアログボックスの［コンパイラ］，［リンカ］，［ディレクトリ/条件］，［パッケージ］，および［バージョン情報］の各ページの現在の設定を DEFPROJ.DOF ファイルに書き込むことができます。このファイルは，［プロジェクトオプション］ダイアログボックスの［デフォルト］ボックスにチェックマークを付け，［OK］を選択すると作成されます。このファイルにデフォルトとして格納されたプロジェクトオプションの設定は，新しく作成するプロジェクトに適用されます。

オブジェクトリポジトリのテンプレートから独自のオプションファイルを持つプロジェクトを作成した場合，その設定は DEFPROJ.DOF のデフォルトの設定を変更します。

Form options1067048

［プロジェクトオプション］ダイアログボックスの［フォーム］ページのオプションでは，プロジェクトのメインフォームとして指定するフォームを変更したり，実行時のフォームの作成順を指定することができます。詳細は「プロジェクトのメインフォームとしてフォームを指定する」を参照してください。

Application options1067049

［アプリケーション］ページでは，プロジェクトのタイトル，ヘルプファイル，アイコンを指定します。これらのオプションをデフォルトの設定として指定することもできます (また，Application オブジェクトの Title，HelpFile，Icon プロパティを使って，実行時にコード内でこれらの項目の取得および設定が行えます)。

タイトル(T)	ここに入力したテキストは，実行中のアプリケーションをアイコン化したときにそのアプリケーションアイコンの下に表示されます。タイトルを指定しないと，アプリケーションアイコンの下には .EXE ファイルのファイル名が表示されます。
ヘルプ	プロジェクトの Windows ヘルプ (.HLP) ファイルを作成する場合は，このファイルを［ヘルプファイル(F)］編集ボックスで指定し，アプリケーションに接続します。既存のヘルプファイルを選択するには，ファイル名を入力するか［参照(B)］ボタンを使用します。 ヘルプファイル名は，実行時に Application オブジェクトの HelpCommand，HelpContext，HelpJump の各メソッドによって使われます。アプリケーションのヘルプメソッドはすべて，ヘルプファイルの名前を渡して Windows API の WinHelp 関数を呼び出します。 注意 実行形式ファイルからみたヘルプファイルの場所は，開発環境と配布されたアプリケーションの環境とでは異なる場合もあることに注意してください。完成したヘルプファイルを格納するドライブ名を事前に確認できない限り，パスにドライブ名を指定するのは避けてください。 WINHELP.EXE がヘルプファイルを検索する方法についての詳細は，Windows ヘルプに関するドキュメントを参照してください。
アイコン(I)	Delphi はすべてのプロジェクトにデフォルトアイコンを提供します。デフォルトアイコンは，実行中のアプリケーションをアイコン化したときや，Windows のエクスプローラまたはプログラムマネージャでアプリケーションを表示したときに表示されます。アプリケーションのアイコンとして，デフォルトアイコン以外のものを指定することもできます。Delphi のイメージライブラリが提供するアイコンファイルは，そのまま変更せずに使用することも，Delphi のイメージエディタで変更して使用することもできます。また，Windows 標準のアイコン形式 (.ICO) のファイルであれば，どれでも指定できます。指定されたアイコンは，コンパイルされてプロジェクトの実行形式ファイルに入れられます。
Compiler options1067050

［コンパイラ］ページでは，コード作成，構文，実行時エラー，デバッグ，メッセージのコンパイルオプションを指定できます。

Linker options1067051

［リンカ］ページでは，プログラムファイルのリンク方法を指定できます。また，リンカ出力作成オプション，.EXE と .DLL オプションも含まれます。

［TD32 デバッグ情報を含める(T)］にチェックマークを付けると，デバッグ情報が実行形式ファイルに入ります (これによってファイルのサイズは大きくなります)。

Directory and Conditional options1067052

［ディレクトリ/条件］ページでは，プロジェクトをコンパイルした出力の位置を設定し，アプリケーションをコンパイル，リンク，配布するためのリソースの場所を指定できます。

出力ディレクトリ	コンパイルしたプロジェクトをプロジェクトディレクトリ以外のディレクトリに出力する場合は，［出力ディレクトリ(O)］編集ボックスにパスを入力します。指定のディレクトリは必ず存在し，コンパイル時にアクセス可能でなければなりません。そうでない場合は，コンパイルエラーになります。
ユニット出力ディレクトリ	コンパイルしたユニットファイルを格納するディレクトリを指定するには，この編集ボックスを使用します。
検索パス	［検索パス(S)］編集ボックスでは，プログラムのコンパイルで使用する Delphi 以外のライブラリファイルの場所を指定します。Delphi のコンパイラはリソースを検索するときに，必ず BIN サブディレクトリと LIB サブディレクトリも検索対象にします。この 2 つのディレクトリとは異なる場所にあるライブラリにアクセスする場合は，この編集ボックスにライブラリのパスを指定します。詳細はオンラインヘルプを参照してください。
デバッガ検索パス	デバッガ用の検索パス。デバッガはコンパイラがデフォルトで定義するパスを検索します。最後にコンパイルされてからディレクトリの構造が変更されている場合，ここでパス名を入力して，デバッグセッションに 1 つまたは複数のファイルを含めることができます。
条件定義	条件コンパイラ指令で参照するシンボルは［条件定義(C)］編集ボックスに入力します。詳細はオンラインヘルプを参照してください。
ユニットの別名	下位互換性に役立ちます。名前変更した可能性のあるユニットまたは単一ユニットにマージされたユニットのエリアス名を指定します。書式は < 旧ユニット名 >=< 新ユニット名 > です。複数のエリアス名をセミコロンで区切って指定できます。デフォルト値は WinTypes=Windows; WinProcs=Windows.Default です。
Version Information1067053

［バージョン情報］ページは，構築するプロジェクトにバージョン情報を含むかどうか，どのように表示するか，構築属性も含めて指定します。情報はコードのタグに含まれています。Windows の Explorer (またはデスクトップ) でコンパイル済みの .EXE ファイルや .DLL ファイルを右クリックして，メニューから［プロパティ］を選択すると，［プロパティ］ダイアログボックスに追加されたページに，指定したバージョン情報が表示されます。

Packages1067054

［パッケージ］ページは，どの設計時パッケージをプロジェクトで使用するかを指定します。また，オプションでどの実行時パッケージを配布アプリケーションに含めるかを指定します。［実行時パッケージを使って構築(B)］編集ボックスにリストしたパッケージは，コンパイルするとき自動的にプロジェクトにリンクされます。「パッケージの使い方」に，Delphi とともに納品されるパッケージがリストされています。設計時パッケージと［コンポーネント］パレットは付属しており，実行時パッケージとユニットも含まれています。


Restoring Delphi's original default settings
Restoring Delphi's original default settings1067055

Section topics	参照

Delphi を初期状態に戻すには，DEFPROJ.DOF ファイルを削除するか名前変更します。


Setting environment preferences
Setting environment preferences1067056

Section topics	参照

プロジェクトの設定を変更するだけでなく，Delphi の環境 (エディタ，デザイナ，デバッガ，コンパイラ) もカスタマイズできます。［環境オプション］ダイアログボックスで設定した環境設定はすべての Delphi プロジェクトに影響します。

環境設定を指定するには，［ツール(T)｜環境オプション(O)］を選択します。［環境オプション］ダイアログボックスのいずれかのページでヘルプボタンをクリックすると，そのページに関するヘルプが表示されます。

メモ	Delphi のインストールをほかのユーザーと共有している場合，ほかのユーザーがデフォルトのオプション設定を変更することもあります。共有インストール状況の場合は，新しいプロジェクトを作成する前に環境オプションをチェックする方がよいでしょう。


Managing multiple project versions and team development
Managing multiple project versions and team development1067057

Section topics	参照

複雑なプログラムをチームで開発している場合や，複数の開発プロジェクトを管理している場合は，バージョンコントロールシステム (VCS) が不可欠です。バージョンコントロールシステムでは，ファイルのアーカイブの作成，プロジェクトファイルへのアクセスのコントロール，複数のプロジェクト間のバージョントラッキングなどが行えます。

Delphi Developer には Intersolv 社の PVCS Version Manager (別売) に対する組み込みインターフェースがあります。このインターフェースでは，PVCS バージョン 5.1 以降をサポートしています。Delphi は Open Tools API を使用しているので，市販のバージョンコントロールユーティリティはどれでも使用できます。Delphi Client/Server Suite には PVCS のインターフェースと PVCS 自体の両方が含まれています。

Enabling team development support1067058

Delphi 組み込みのチーム開発サポートを使用するには，あらかじめ PVCS をシステムの指定されたディレクトリに格納しておかなければなりません。また，いくつかのファイルが \WINDOWS\SYSTEM ディレクトリ内になければなりません。

Delphi のチーム開発サポート機能の使い方についての詳細は，［Workgroups(W)｜Browse PVCS Projects］を選択して PVCS のプロジェクトウィンドウを表示し，ヘルプアイコンをクリックして PVCS のヘルプシステムを参照してください。また，PVCS については PVCS.HLP ファイルでもオンラインヘルプを見ることができます。


Compiling, building, and running projects
Compiling, building, and running projects1067059

Section topics	参照

すべての Delphi プロジェクトに共通な目標は，実行形式ファイルとして .EXE ファイルまたは .DLL ファイルを 1 つ作成することです。アプリケーションの開発のさまざまな段階で，.EXE ファイルや .DLL ファイルをコンパイル，構築，実行して，アプリケーションを表示したりテストできます。また，プロジェクトをコンパイルせずにソースコードの構文チェックをすることもできます。


Checking source code syntax
Checking source code syntax1067060

Section topics	参照

コンパイルしないで，プロジェクトのソースコードを構文チェックを実行することができます。そのチェック方法はコンパイル時のチェック方法と同じで，コードにエラーがあると同じエラーメッセージを生成します。しかし，構文チェックではオブジェクトコードは生成されません。そのため，チェック時間が速くなりますが，チェックに成功しても実行形式ファイルは生成されません。

プロジェクトソースコードの構文チェックを行う手順は次のとおりです。

1.	プロジェクトソースコードを保存します。ただしこれは必須ではありません。

2.	Delphi のメニューバーで［プロジェクト(P)｜構文チェック(S)］を選択します。

カーソルが待ち状態の形になり，構文チェック中であることを示します。チェック後，エラーが発生しなかったときは通常のカーソルに戻ります。エラーが発生したときは以下の状態になります。

コードエディタウィンドウが前面に表示される

エラーを含むユニットソースファイルページがコードエディタの前面に表示される

エラーの発生した行がコードエディタで強調表示される

コードエディタのメッセージウィンドウにエラーメッセージが表示される

エラー行が強調表示され，フォーカスがあるときに〔F1〕キーを押すと，エラーメッセージに関する状況感知型のヘルプを利用できる

構文エラーまたはコンパイルエラーの表示


Compiling a project
Compiling a project1067061

Section topics	参照

最後にコンパイルした後で変更したすべてのソースコードファイルをコンパイルするには次のようにします。

Delphi のメニューバーで［プロジェクト(P)｜コンパイル(C)］を選択します。

このコマンドを選択すると，以下のような処理が行われます。

コンパイラは，最後にコンパイルした後にソースコードが変更されたすべてのユニットをコンパイルします。それぞれのユニットに対して，.DCU (Delphi Compiled Unit) という拡張子の付いたファイルが作成されます。
コンパイラがユニットのソースコードファイルを見つけられないと，ユニットは再コンパイルされません。

ユニットソースコードの interface 部に変更がある場合は，これに依存するほかのすべてのユニットが再コンパイルされます。
ユニットのインターフェース部についての詳細は，「コードエディタの使い方」を参照してください。

ユニットが .OBJ ファイル (アセンブリ言語コードを含むファイル) にリンクしており，.OBJ ファイルがユニットの .DCU ファイルよりも新しい場合は，ユニットは再コンパイルされます。

ユニットにインクルード (.INC) ファイルがあり，このインクルードファイルがユニットの .DCU ファイルよりも新しい場合は，ユニットは再コンパイルされます。

プロジェクトを構成するすべてのユニットをコンパイルすると，Delphi はプロジェクトファイルをコンパイルし，実行形式ファイルまたはダイナミックリンクライブラリを作成します。このファイル名は，プロジェクトソースコードファイルと同じ名前に拡張子 .EXE または .DLL が付いたものです。これで，このファイルには各ユニットのすべてのコンパイルされたコードとフォームが入りました。つまり，実行形式ファイルは実行できる状態になりました。

ソースコードで {$IFDEF} 条件指令と定義済みシンボルを使用すると，コードの特定の部分だけを選択してコンパイルすることができます。詳細については「条件コンパイル指令の使い方」を参照してください。

Obtaining compile status information1067062

プロジェクトのコンパイル状態に関する情報を取得するには，［プロジェクト(P)｜情報(I)］を選択し，［情報］ダイアログボックスを表示します。このダイアログボックスはコンパイルしたソースコードの行数，コードとデータのバイトサイズ，スタックサイズとファイルサイズ，プロジェクトのコンパイル状態に関する情報を表示します。

［環境オプション］ダイアログボックスの［設定］ページで［コンパイル状況の表示(C)］ボックスにチェックマークを付けると，プロジェクトのコンパイル中にコンパイラの状態情報を表示できます。詳細はオンラインヘルプの「環境オプション」を参照してください。


Building a project
Building a project1067063

Section topics	参照

最後のコンパイルの後で変更があったかどうかに関係なく，プロジェクトのすべてのソースコードファイルをコンパイルするには次のようにします。

Delphi メニューバーで［プロジェクト(P)｜再構築(B)］を選択します。

このコマンドの結果は［プロジェクト(P)｜コンパイル(C)］の結果と似ています。異なる点は，最後のコンパイルの後の変更があるかないかに関係なく，プロジェクトのすべてのユニットがコンパイルされるという点です。［再構築(B)］は，ファイルを変更したかどうか不明の場合やすべてのファイルのコンパイル時期を統一する場合に便利です。また，グローバルなコンパイラ指令を変更したときにも，すべてのコードを正しい状態でコンパイルすることを保証するために重要となります。


Running a project
Running a project1067064

Section topics	参照

プロジェクトは Delphi 内でテスト実行できます。また，Delphi を実行せずに Windows 環境から直接コンパイル済みの .EXE ファイルを実行できます。

アプリケーションをコンパイルして，これを Delphi 内で実行するには以下の方法があります。

Delphi のメニューバーで［実行(R)｜実行(R)］を選択する

Delphi のスピードバーで［実行］ボタンを選択する

これらの操作は，［プロジェクト(P)｜コンパイル(C)］を選択するのとほぼ同じです。異なる点は，コンパイルが成功するとただちにアプリケーションが実行される点です。

Executing a project from Windows1067065

コンパイラは完全にスタンドアロンの実行形式ファイル (.EXE) を作成するので，通常の Windows アプリケーションを実行する場合と同じように，Windows 環境からアプリケーションを実行できます。

プロジェクトにアイコンを指定すると，Windows エクスプローラのファイル名の隣，デスクトップのショートカット，Windows の［スタート｜プログラム(P)］メニュー，そして実行中にアプリケーションを最小化したときはタスクバーにアイコンが表示されます (詳細はオンラインヘルプを参照)。


See also1067066

コンパイラ指令

コマンドラインコンパイラ

Object Pascal のユニット

コードエディタでのファイルの表示

フォームをプロジェクトのメインフォームとして指定する

［プロジェクトオプション］ダイアログボックス

［環境オプション］ダイアログボックス


Understanding components
Understanding components1078001

Section topics	参照

Delphi のビジュアル設計ツールを使うと，設計要素を繰り返し作成するのではなく再利用して，アプリケーションのビジュアルな要素を手早く作成することができます。また，設計ツールを使って作業するとき，Delphi はユーザーのために対応する Pascal コードを作成します。

Delphi でのユーザーインターフェースの設計は，もっとも簡単なレベルで次の 4 ステップより構成されます。

1.	フォームの作成

2.	フォームへのコンポーネントの追加

3.	コンポーネントのプロパティの設定

4.	コンポーネントのイベントへのコードの作成

この章では以下の事項について説明します。

Delphi のフォームとコンポーネントに関する基本的な解説

ジョブにふさわしいコンポーネントを選択するためのヘルプ

コンポーネントパレットのカスタマイズの手順


Forms, the basic building blocks
Forms, the basic building blocks1078002

Section topics	参照

Delphi でのビジュアルな設計作業はすべてフォームの上で行われます。ユーザーが設計したフォームは，アプリケーションのウィンドウやダイアログボックスとなります。フォームに追加するコンポーネントには，ユーザーのアプリケーション操作のコントロールがあります。その他にフォームに追加できるコンポーネントとしては，データベースのようなアプリケーション要素があります。

特殊なオブジェクトとしては，ほかにデータモジュールがあります。データモジュールには，アプリケーションのユーザーが直接対話しないデータベースのような非ビジュアルコンポーネントが含まれているため，アプリケーション実行中は表示されません。

フォームとフォームが含むコンポーネントを区別すると便利ですが，フォームもまたコンポーネントです。したがって，フォームのプロパティの読み出しや設定，メソッドの読み出し，イベントへの応答を行うことができます。


Overview of components
Overview of components1078003

Section topics	参照

フォームに追加したそれぞれのコンポーネントは，ユーザーインターフェースオブジェクト，データベースオブジェクト，またはシステムタイマーのようなシステム関数となります。フォームにコンポーネントを作成することにより，アプリケーションのインターフェースを構築できます。

コンポーネントは，本当の意味でオブジェクト指向プログラミング (OOP) のオブジェクトです。オブジェクトとしての Delphi コンポーネントには，次のような特徴があります。

データとデータアクセス関数の一部をカプセル化する

派生元 (上位オブジェクト) のオブジェクトからデータと動作を継承する

共通の上位オブジェクトから派生したほかのオブジェクトと多態性と呼ばれる概念を通して動作の互換性を保つ

それぞれのコンポーネントは独自の様相を持っていますが，すべてのコンポーネントは TComponent と呼ばれる共通の上位オブジェクトから継承した特定の性質を共有しています。TComponent は，Delphi の環境でコンポーネントが動作するのに必要な最小限の属性セットを定義します。

すべてのコンポーネントに共通の属性については，「コンポーネントの共通要素」で説明します。

この時点でコンポーネントに関して理解すべき重要な点は，コンポーネントが以下の 3 つの情報を含んでいるということです。

状態の情報。コンポーネントの現在の状態に関する情報は，コンポーネントのプロパティと呼ばれます。プロパティは，ユーザーやアプリケーションによる読み出しや設定ができるコンポーネントの名前付き属性です。たとえば，Height や Color はコンポーネントのプロパティの例です。

動作情報。コンポーネントは，一般的に必要に応じて特定の動作を実行します。これらの動作はメソッドにより定義されます。メソッドとは，コンポーネントの動作をコードで呼び出す手順や関数のことです。Hide や Refresh はコンポーネントのメソッドの例です。

フィードバック情報。コンポーネントは，アプリケーション開発者が出来事やイベントを指定するコードを作成してコンポーネントを対話型にする機会を提供します。イベントに対応することで，アプリケーションが生きたものとなります。OnClick や OnKeyDown はコンポーネントのイベントの例です。


Delphi's standard components
Delphi's standard components1078004

Section topics	参照

Delphi のコンポーネントパレットには，Delphi のアプリケーションで使用できるコンポーネントが多数含まれています。ユーザーはパレットのコンポーネントを選択して，追加，削除，再調整を行うことができます。また，多数のコンポーネントから構成されるコンポーネントテンプレートを作成して，それをコンポーネントパレットに追加できます (「コンポーネントテンプレートの使い方」参照)。

パレット上のコンポーネントは，機能によってページにグループ化されています。表 5.1 は，デフォルトのページとそれらが含むコンポーネントの種類の一覧です。

ページ名	内容
Standard	標準ウィンドウコントロール，メニュー
Additional	カスタマイズされたコントロール
System	システムレベルのアクセス用コンポーネントおよびコントロール。タイマー，ファイルシステム，マルチメディア，および DDE を含む
Win32	Windows 95 / NT 4.0 のコモンコントロール
Dialogs	Windows コモンダイアログボックス
Data Access	データベース，テーブル，問い合わせ，レポートにアクセスする非ビジュアルコンポーネント
Data Controls	ビジュアル，データベース対応コントロール
Win 3.1	Delphi 1.0 プロジェクトと互換性のあるコンポーネント。このページのボックスコンポーネントも 32 ビットダイアログボックスと互換性のあるカスタムダイアログボックスの構築に役立つ
Internet	さまざまなインターネット通信プロトコル用コンポーネント，低レベル TCP/IP 管理用ソケット，Web サーバーアプリケーション構築用オブジェクト
Samples	カスタムコンポーネントのサンプル。ゲージ，カラーグリッド，スピンボタン，ディレクトリアウトライン，カレンダーグリッド，IBEvent Alerter など
Qreport	組み込みのレポートを簡単に作成する Quick Report コンポーネント
Decision Cube	データベースの情報を要約して，分析のフォーカスをその都度変更しながら，さまざまな手法で表示する
ActiveX	ActiveX サンプルコントロール
デフォルトのパレットに表示される各コンポーネントに関する概説は，コンポーネントパレットの各ページを選択して〔F1〕を押してください。ビジュアルコンポーネントライブラリの各コンポーネントの詳細な解説を見るには，そのコンポーネントをパレットからフォームに配置し，そのコンポーネントを選択して〔F1〕を押してください。


Two views of components
Two views of components1078005

Section topics	参照

前述したように，コンポーネントはアプリケーションの要素を再利用可能な標準的方法でカプセル化します。Delphi を理解するには，このコンポーネントモデルを理解することがもっとも重要なステップです。

Delphi のコンポーネントはさまざまな方法で分類できます。それぞれの方法にはコンポーネントをさらに効率的に利用できる助けとなるような情報が含まれています。

この節では，Delphi のコンポーネントを階層的に分けた場合と機能的に分けた場合について説明します。階層的な分類では「何であるか」に従ってコンポーネントを分類しているのに対し，機能的な分類では「何に使うか」に従って分類しています。


The component hierarchy
The component hierarchy1078006

Section topics	参照

コンポーネントを理解する方法の 1 つに，オブジェクトとしての関係を理解する方法があります。つまり，異種のコンポーネントが共有する継承関係を調べます。さまざまなコンポーネントグループが継承する共通のプロパティ，メソッド，イベントを調べれば，類似点と相異点を理解できます。

ここでは，Delphi の VCL (ビジュアルコンポーネントライブラリ) の階層全体を詳細に説明するのではなく，大まかなコンポーネントカテゴリだけを紹介します。VCL 階層についての詳細は，『ビジュアルコンポーネントライブラリリファレンス』と『開発者ガイド』を参照してください。

次の図に Delphi で主に使うコンポーネントの種類を簡単に示します。1078007

一般的に，コンポーネントは，非ビジュアルコンポーネントとコントロールの2つに大きく分けられます。

非ビジュアルコンポーネントは，システムタイマーやデータベース接続のようにユーザーが直接対話できないプログラム要素を表すコンポーネントです。非ビジュアルコンポーネントは設計時にはフォームまたはデータモジュール上に小さなアイコンとして表示されます。このアイコンを使ってコンポーネントを選択し，プロパティを設定したり，イベントハンドラを結び付けたりできます。
非ビジュアルコンポーネントの中には，メインメニューバーや Windows コモンダイアログボックスのように，アプリケーションの実行中にビジュアルな要素になるものがあります。この場合，非ビジュアルコンポーネントは，実行時にのみ存在する項目の設計時インターフェースであり，実行中に必要に応じてアプリケーションが作成する項目の情報を格納します。

コントロールは実行時にユーザーが対話できるビジュアルな要素です。一般的に，設計時も実行時も同様に表示されるので，フォームのレイアウトが容易です。設計時にも，コントロールの表示と動作はできる限り最新の状態に更新されます。たとえばリストボックスには項目リストが表示され，アクティブなデータセットに接続されたデータグリッドには実際のデータが表示されます。
コントロールは，さらにウィンドウコントロールとグラフィックコントロールに分かれます。

ウィンドウコントロールは入力フォーカスを受け取れます。標準の Windows コントロールのほとんどがウィンドウコントロールです。「ウィンドウ」という名前は，コントロールがウィンドウハンドル (Handle プロパティを使ってアクセスできる) をもっていることに由来します。

グラフィックコントロール (「非ウィンドウコントロール」とも呼ばれる) はフォーカスを受け取れません。ウィンドウハンドルはありません。システムリソースの消費量が少ないので，いくつものコントロールを表示する必要のある複雑なフォームの場合に役に立ちます。

ユーザーインターフェースを設計する場合，ウィンドウコントロールとグラフィックコントロールの区別が重要なことがあります。たとえば，ボタンがいくつもあるツールバーを作成する場合，標準の Windows ボタンコンポーネントを使用できますが，それぞれにウィンドウハンドルが必要です。かわりに，ウィンドウを持たないスピードボタンコンポーネントを選択すれば，システムリソースの消費量を大幅に削減できます。


Functional divisions
Functional divisions1078008

Section topics	参照

コンポーネントを理解するもう 1 つの方法は，その機能を調べることです。類似したコンポーネントを比較すると，特定のタスクに最適なコンポーネントを探せます。ほとんどの場合，必要な動作をすべて実行できるコンポーネントがいくつかありますが，容量が多いか，処理効率がよいか，システムリソースへの影響が小さいかなどの観点から，1 つだけを選択します。

表は，Delphi のコンポーネントにより実行できるすべてのタスクを詳細に説明するのではなく，一般的なユーザーインターフェースのタスクカテゴリとそれに属するコンポーネントだけを紹介しています。コンポーネントの機能比較については，「適切なコンポーネントの選び方」を参照してください。

タスクカテゴリ	コンポーネント	参照トピック
テキストの 入力と処理	EditBox，Memo，MaskEdit，RichEdit，DBText，DBEdit，DBMemo	テキストコントロール
特殊入力	ScrollBar，TrackBar，UpDown，HotKey	特殊入力コントロール
ボタン入力と オプション選択	Button，CheckBox，RadioButton，BitmapButton，SpeedButton，DBCheckBox，DBRadioButton，TabSet	ボタンおよび類似のコントロール
リストの表示と処理	ListBox，ComboBox，TreeView，ListView，DBListBox，DBCheckBox，DBLookupListBox，DBLookupComboBox	リストの処理
グループ化	GroupBox，RadioGroup，Panel，ScrollBox，TabControl，PageControl，HeaderControl，TabbedNotebook，Notebook	コンポーネントのグループ化
情報の表示	Label，ProgressBar，StatusBar，Panel	情報の表示
グリッド（表）の表示	StringGrid，DrawGrid，DBGrid，DBControlGrid	グリッドの表示
グラフィックの表示	Image，Shape，Bevel，ImageList，PaintBox	グラフィックの表示
Windows コモン ダイアログボックス	OpenDialog，SaveDialog，FontDialog，ColorDialog，PrintDialog，PrinterSetupDialog，SearchDialog，ReplaceDialog	Windows コモンダイアログボックス


Common component elements
Common component elements1078009

Section topics	参照

すべてのコンポーネントには，プロパティ，メソッド，イベントが組み込まれています。これらの中には上位コンポーネントから継承するものもあります。これは，コンポーネントが他のコンポーネントの要素を共有することを意味します。このような要素を共通要素と呼びます。たとえば，すべてのコントロールは Height プロパティを継承します。Height プロパティはコントロールの垂直方向のサイズを表すものなので，すべてのコントロールに共通のプロパティです。

コンポーネントにはその種類ごとにキー要素と呼ばれる独自の要素があります。たとえば，チェックボックスコンポーネントには，チェックマークが付いているかどうかを示す Checked プロパティがあります。このプロパティはチェックボックスに固有のもので，ライブラリリファレンスやオンラインヘルプでは「キー」シンボルを使って強調されます。

The Name property1078010

すべてのコンポーネントに共通のプロパティがいくつかありますが，その中でもっとも重要なものは Name プロパティです。Name は他のプロパティと異なり，アプリケーションのすべてのコンポーネントは重複しない名前を持たねばなりません。最初から具体的な固有の名前を付けるようにすれば，コードがわかりやすくなり，将来名前が重複するのを防げます。

コンポーネントの名前は Object Pascal 識別子の標準的な命名規則に従って付けます。Object Pascal の命名規則に従わない値を入力した場合，名前はその値には変更されず，次のエラーメッセージが表示されます。

コンポーネント名に "<name>" は使えません.

Object Pascal の命名規則についての詳細は「Object Pascal コードの書き方」を参照してください。

注意	オブジェクトインスペクタを使ってコンポーネントの Name プロパティを変更する限りは，この変更はソースコードにも反映されます。しかし，コードエディタを使って直接コンポーネント名を入力して編集した場合は異なります。コンポーネント名を手作業で編集した場合には，Delphi はそのフォームを読み込めなくなります。


Choosing the right component
Choosing the right component1078011

Section topics	参照

Delphi には多種多様のコンポーネントがあります。その多くは類似した機能をそれぞれ独自の方法で実行します。この節では，類似したコンポーネントの中から適切なものを選択する方法について説明します。まず，すべてのコンポーネントに共通するプロパティについて説明します。その後で，コンポーネントの機能別グループと，グループから適切なコンポーネントを選択する方法について説明します。そして，グループ内の各コンポーネントを特徴付けているプロパティについても簡単に説明します。


Properties common to all components
Properties common to all components1078012

Section topics	参照

すべてのコンポーネントには，共通するプロパティが数多くあります。実際にはそれらのプロパティがコンポーネントを構成します。すべてのコンポーネントに共通するプロパティがわかれば，アプリケーションの作成に使う特定のコンポーネントを定義する固有のプロパティを評価しやすくなります。

共通のプロパティは次のカテゴリーに分かれます。

位置とサイズのプロパティ

表示プロパティ

親プロパティ

移動 (ナビゲーション) プロパティ

ドラッグアンドドロッププロパティ

Position and size properties1078013

フォーム上のコントロールの位置とサイズを定義するプロパティは 4 つあります。

Height は，垂直方向のサイズを設定する

Width は，水平方向のサイズを設定する

Top は，上端の位置を決める

Left は，左端の位置を決める

これらのプロパティは，非ビジュアルコンポーネントではアクセスできません。ただし，フォームに追加したコンポーネントアイコンの位置は記録されています。

設計時間のほとんどは，フォーム上のコントロールのイメージを操作したり位置合わせパレットを使ってこれらのプロパティを設定/変更することに費やされます。しかし，これらのプロパティは実行時にも変更できます。

Display properties1078014

コントロールの外観を制御するプロパティは 4 つあります。

BorderStyle は，コントロールが境界を持つかどうか指定する

Color は，コントロールの背景色を変更する

Ctrl3D は，コントロールの外観が 3 次元か 2 次元かを指定する

Font は，テキストの色，フォントの種類，スタイルまたはサイズを変更する。サイズや色のようなフォントの要素を別々に設定することも，［フォントの指定］ダイアログを使って複数の要素を一度に変更することもできる

Parent properties1078015

アプリケーションの外観を統一するために，コントロールの外観をそのコンテナの表示プロパティによって決めるようにできます。ParentColor，ParentFont，または ParentCtrl3D の親プロパティをTrueに設定すると，表示の編集内容はフォーム上のすべてのコンポーネントに自動的に更新されます。

対応する親プロパティを True に設定した後で，Font，Color または Ctrl3D のいずれかを変更すると，選択した色またはフォントが有効になり，対応する親プロパティは False になります。

Navigation properties1078016

フォームのコントロール間をユーザーが移動する方法を決めるプロパティは3つあります。

Caption プロパティはコンポーネントに付けるラベルのテキスト文字列を保持する。文字列の文字に下線を付けるには，文字の前に & (アンド記号) を付ける。このような文字をアクセラレータ文字という。ユーザーは，〔Alt〕を押しながら下線付き文字を入力して，コントロールまたはメニュー項目を選択できる

TabOrder プロパティは，親のタブ順でのコントロールの位置，つまり，ユーザーが〔Tab〕を押したときにコントロールがフォーカスを受け取る順序を示す。最初はコンポーネントをフォームに追加した順序がタブ順になっているが，TabOrder を変更すればタブ順を変更できる。TabOrder が有効なのは，TabStop が True の場合のみ

TabStop プロパティは，ユーザーが〔Tab〕キーを使ってコントロールに移動できるかどうかを決める。TabStop を True に設定すると，コントロールはタブ順に入る

Drag-and-drop properties1078017

ドラッグアンドドロップ動作を制御するコンポーネントプロパティは 2 つあります。

DragMode プロパティは，ドラッグの開始方法を決める。デフォルト値は dmManual であり，この場合，ドラッグを開始するには BeginDrag メソッドを呼び出す必要がある。DragMode の値が dmAutomatic の場合は，マウスボタンを押すとすぐにドラッグが始まる

DragCursor プロパティは，オブジェクトのドラッグ先コンポーネントにマウスポインタを移動したときのポインタの形状を決める

アプリケーションでのドラッグアンドドロップの使い方については「統合デバッガの使い方」を参照してください。


Text controls
Text controls1078018

Section topics	参照

多くのアプリケーションでは，ユーザーにテキストを入力させたり，ユーザーに対してテキストを表示したりしなければなりません。情報の保持に使われるコントロールの種類は，情報のサイズや形式によって異なります。

コンポーネント	用途
Edit	単一行のテキストの編集
Memo	複数行のテキストの編集
MaskEdit	郵便番号や電話番号のような特定の書式のテキストの編集。 マスクを構成する特殊文字については，『ライブラリリファレンス』またはオンラインヘルプを参照
RichEdit	無制限の行数のテキスト，またはリッチテキスト形式の編集
Properties common to all text controls1078019

すべてのテキストコントロールには，以下の共通プロパティがあります。

Text プロパティは，編集ボックスやメモコントロールに表示されるテキストを指定する

CharCase プロパティは，入力されたテキストを，小文字だけ，小文字と大文字，大文字だけのいずれかに変換する

ReadOnly プロパティは，ユーザーによる変更を制限するかどうかを指定する。デフォルトでは，すべてのテキストコントロールが編集可能である

MaxLength プロパティは，編集ボックスの文字数を制限する

PasswordChar プロパティは，1 文字を割り当ててユーザーが入力した文字を隠す。PasswordChar は，ユーザーのパスワードの代わりにアスタリスクを表示するのによく使われる

HideSelection プロパティは，コントロールにフォーカスがなくなっても，選択したテキストを強調したままにするかどうかを指定する

Properties shared by memo and rich text controls1078020

メモコントロールとリッチテキストコントロールには，すべてのテキストコントロールに共通するプロパティのほかに，お互いに共通するいくつかのプロパティがあります。

Alignment プロパティは，コンポーネント内でのテキストの揃え方 (左揃え，右揃え，中央揃え) を指定する

Lines プロパティは，メモまたはリッチテキストコントロールのテキストを文字列リストとして保持する

OEMConvert プロパティは，コントロール内のテキストを OEM 文字に変換するかどうかを決める。このプロパティの値が True の場合，テキストは OEM 文字に変換されるが，それ以外は ANSI 文字のままである

WordWrap プロパティは，右マージンでテキストを改行するかどうかを決める

WantReturns プロパティは，ユーザーがメモコントロールまたはリッチテキストコントロールで〔Enter〕を押して入力する改行文字が，コントロール内のテキストに影響するか，それともフォームに移動するかを決める。WantReturns が True の場合，ユーザーが〔Enter〕を押すと改行文字はメモコントロールまたはリッチテキストコントロールに入力される。それ以外の場合，改行文字はフォームに渡される

WantTabs プロパティが True の場合，ユーザーはメモコントロールにタブ文字を入力できる

Memo controls1078021

メモコントロールは編集ボックスコンポーネントと同様にテキストを処理しますが，複数のテキスト行を処理できます。

メモ内のテキストは Text プロパティの値である。Modified プロパティを使用すると，テキスト変更の有無をアプリケーションが通知できる

メモ内のテキストをコントロール可能になったら必ず自動的に選択されるようにするには，AutoSelect プロパティを True に設定する

SelectAll メソッドを使うと，実行時にメモ内のすべてのテキストを選択できる

ユーザーがメモ内のどのテキストを選択したかを見つけたり，選択テキストを置き換えるには，SelText プロパティを使う

テキストの一部分だけを選択したり，テキストの選択部分を見つけるには，SelStart と SelLength プロパティを使う

Rich text controls1078022

リッチテキストコンポーネントは，リッチテキストをサポートするメモコントロールです。つまり，個々の文字，語，パラグラフの形式を変更できます。このコントロールには，パラグラフの書式情報を保持する Paragraphs プロパティがあります。また，印刷機能や文字検索機能もあります。

リッチテキストエディタは，デフォルトで以下のものをサポートします。

Font プロパティ (書体，サイズ，色，太字，斜体など)

Format プロパティ (位置揃え，タブ，インデント，番号付けなど)

選択したテキストの自動ドラッグアンドドロップ

書式付きまたは書式なしテキストの表示。PlainText が True の場合，書式は除かれる


Specialized input controls
Specialized input controls1078023

Section topics	参照

特殊な入力を扱う以下のコンポーネントが使えます。

コンポーネント	用途
ScrollBar	連続した範囲内の値を選択する
TrackBar	連続した範囲内の値を選択する（ScrollBar よりも視覚効果が高い）
UpDown	Edit コンポーネントに結び付けた増減ボタンを使って値を選択する
HotKey	〔Ctrl〕，〔Shift〕，〔Alt〕のキーシーケンスを入力する
Splitter	位置合わせが行われるコントロールをサイズ変更する
Scroll bars1078024

ScrollBar コンポーネントは，Windows のスクロールバーです。ウィンドウ，フォーム，コントロールの内容をスクロールするのに使います。ユーザーがスクロールバーをスクロールしたときに応答するウィンドウ，フォーム，コントロールの動作を指定するコードは，OnScroll イベントハンドラに作成します。

LargeChange は，ユーザーがスクロールボックスのどちらかの側でスクロールバーをクリックしたときのスクロールボックスの移動量を決める

SmallChange は，ユーザーがスクロールバーの端の矢印をクリックするかキーボードの矢印キーを使ったときのスクロールボックスの移動量を決める。デフォルトは 1

Min プロパティと Max プロパティの値は，ユーザーがスクロールバーをスクロールしたときに，スクロールボックスがスクロールバー上で移動できる位置数を決める

Position プロパティを使うと，アプリケーションはスクロールボックスの位置を設定したり，スクロールバーの現在の位置を決めたりできる

Track bar controls1078025

トラックバーは，たとえばボリュームや明るさなどに連続した範囲で整数値を設定/調整できます。トラックバーは調整範囲を示すバーとインジケータで構成されます。インジケータはコントロールの現在値を示し，値の変更に使われます。

ユーザーは，スライドインジケータを特定の位置にドラッグして移動するか，トラックバーのホットゾーンをクリックしてインジケータを直接その位置に移動します。

トラックバーの範囲の上端と下端を設定するには，Max プロパティと Min プロパティを使う

選択範囲を強調表示するには，SelEnd プロパティと SelStart プロパティを使う。図を参照

デフォルトでは，トラックバーの下に 1 行の目盛りが表示される。TickMarks プロパティを tmNone に設定すると目盛りが除かれ，tmBoth に設定すると上下両側に目盛りが付けられる。図を参照

トラックバーの向きを水平または垂直に設定するには Orientation プロパティを使う

TickStyle は目盛りの設定が自動か手動かを制御する

Position プロパティはトラックバーのデフォルトの位置を設定し，実行時にユーザーが選択した値の追跡もする

Three views of the track bar component1078026

デフォルトでは，ユーザーが上下の矢印キーを押すと 1 目盛りずつ移動できる。1 回の移動分を変更するには，LineSize を設定する

ユーザーが〔PageUp〕と〔PageDown〕を押したときに移動する刻みの数を指定するには，PageSize を設定する

Up-down controls1078027

アップダウンコントロールは，循環する非連続の値の入力に使うコントロールで，通常はテキストコントロールと組み合わせて使用します。テキストボックスと 1 対のボタンを持つ特殊なコントロールの組み合わせにより，スピンボタンに似たものとなります。

ユーザーがテキストボックスかボタンをクリックすると，コントロールのテキストボックスに入力フォーカスが移ります。ユーザーは，テキストコントロールに直接値を入力したり，ボタンを使って値を増減したりできます。

テキストコントロールにアップダウンコントロールを結びつけるには Associate を使う

結びつけるテキストコントロールの左または右にアップダウンコンポーネントを追加するには，AlignButton プロパティを使う

ボタンの向きを垂直から水平に切り替えるには，Orientation を水平にする

アップダウンコントロールの限界値を設定するには，Max と Min を使う

デフォルトでは，矢印キーを使ってアップダウンコントロールの増減ができる。キーボードを使用不可にするには，ArrowKeys を False に設定する

Position プロパティは，コントロールが上下に移動するときに値を保持する。設計時にデフォルトを設定するには，Position を使う

アップダウンコントロールの値が 1000 を超えると，3 桁ごとの区切り記号が自動的に表示される。この記号を取り除くには，Thousands を False に設定する

デフォルトでは，アップダウンコントロールは最大値で停止する。最大値に達したら最少値に戻すには，Wrap を True に設定する

Hot key controls1078028

コンポーネントにフォーカスを移動するホットキーシーケンスを指定するには，ホットキーコンポーネントを使います。 HotKey プロパティは，ホットキーコントロールの現在のキーの組み合わせを保持します。デフォルトは〔Alt〕+〔A〕です。HotKey プロパティの値を変更するには，値を直接変更するか，Modifiers プロパティの値を設定します。

Modifiers プロパティを使うと，ホットキーとして〔Ctrl〕，〔Alt〕，〔Extra〕，〔Shift〕などの修飾子キーを 1 つまたは複数選択できる。修飾子キーは，文字キー，ファンクションキー，矢印キーなどの修飾子以外のキーと一緒に使う

InvalidKeys プロパティを使うと，1 つまたは複数の修飾子を無効にできる。このプロパティを設定する場合，Modifiers プロパティにデフォルト修飾子も設定する必要がある

Splitter control1078029

位置を揃えた 2 つのコントロールの間にスプリッタを追加すると，ユーザーがそのコントロールのサイズを変更できるようになります。スプリッタは，フォームの一方の端に位置合わせされたコントロールと，クライアント領域の残りの部分を占める他のコントロールの間に配置されます。スプリッタの位置合わせは，フォームの端の起点となるコントロールと同じに設定します。

フォーム上の各コントロールを分離したペインとして使用します。各ペインを配置したら，同じ位置合わせのスプリッタを配置して，ペインがサイズ変更可能となるようにします。フォームに配置する最後のペインの位置合わせはクライアント基準とする必要があり，そうすることで，他のすべてのペインのサイズ変更後に最後のペインが残りの領域すべてを占めるようにサイズ変更されます。

MinSize プロパティは，隣り合うコントロールがサイズ変更されたときに，スプリッタの表示が消える最小サイズを指定する

Beveled プロパティを True に設定すると，スプリッタの端に 3D ベベルの外観が付加される


Buttons and similar controls
Buttons and similar controls1078030

Section topics	参照

アプリケーションでコマンドを起動するときは，メニューから選択する代わりにボタンを使うのが一般的方法です。標準のテキストベースのボタンにはいくつかの変形があります。

コンポーネント	用途
Button	コマンドの選択肢を表す
BitBtn	グリフを使ってコマンドの選択肢を表す
SpeedButton	ツールバーボタンを表示する
CheckBox	二者択一のオプションを表す
RadioButton	相互に排他的な（同時に 1 つしか選べない）選択肢を表す
ToolBar	ツールボタンと他のコントロールを横一列に配置し，サイズと位置を自動的に調整する
CoolBar	移動可能，サイズ変更可能なバンド内にウインドウコントロールを表示する
Button controls1078031

Button コンポーネントは，押しボタンコントロールです。ユーザーはボタンコントロールを選択して操作を開始できます。設計時にボタンをダブルクリックすると，そのボタンの OnClick イベントハンドラがコードエディタに表示され編集できる状態になります。

ユーザーが〔Esc〕を押したときにボタンの OnClick イベントを発生させるようにするには，Cancel を True に設定する

ユーザーが〔Enter〕を押したときにボタンの OnClick イベントを発生させるようにするには，Default を True に設定す。別のコントロールにフォーカスが移動しても，〔Enter〕は OnClick イベントを発生させる

Bitmap buttons1078032

ビットマップボタンコンポーネントは，押しボタンコントロールで，ボタン面にビットマップのイメージを表示できます。ユーザーはビットマップを定義済みのビットマップボタンスタイルから選択することも，自分で作成したビットマップを指定することもできます。

ボタンにカスタムビットマップを選ぶには，Glyph プロパティを設定する

ボタンのイメージとデフォルト動作を自動的に設定するには，Kind を使う。標準のビットマップボタンの一覧については，「標準コマンドボタンの作成」の表を参照

デフォルトでは，グリフはテキストの左側に表示される。位置を移動するには，Layout プロパティを使う

グリフとテキストは自動的にボタンの中央に揃えられる。この位置を移動するには，Margin プロパティを使う。Margin は，イメージの端とボタンの端のピクセル数を指定する

デフォルトでは，イメージとテキストは 4 ピクセルだけ離れている。この距離を増減するには，Spacing を使う

ビットマップボタンには，上がった状態，下がった (押された) 状態，下がったまま (使用不可) の状態の 3 つがある。状態ごとに異なるビットマップイメージを表示するには，NumGlyphs プロパティを 3 に設定する

Speed buttons1078033

スピードボタンコンポーネントは，通常，ボタン面にグラフィックイメージが表示されているボタンで，コマンドの実行またはモードの設定に使われます。スピードボタンには，まとまりとして動作できるというユニークな特性があり，通常はパネルと一緒に使ってツールバーを作成します。

デフォルトでは，スピードボタンは上がった (選択されていない) 状態で表示される。最初からスピードボタンを選択した状態で表示するには，Down プロパティを True に設定する

AllowAllUp が True の場合，同じグループのすべてのスピードボタンはすべて選択されていない状態，つまり「上がった」状態になる。ラジオグループのように動作するボタングループとして使いたい場合は，AllowAllUp を False に設定する

複数のスピードボタンをグループにまとめるには，グループ内のすべてのボタンの GroupIndex プロパティを 0 以外の同じ値に設定する

スピードボタンを使ったツールバーの作成方法については「ツールバーとクールバーの使い方」を参照してください。

Check boxes1078034

チェックボックスを使うと，ユーザーは，はい/いいえ，男/女などのような 2 項目からの選択ができます。

Checked を True に設定すると，チェックボックスにそのオプションが選択されたことを示すチェックマークが表示される

AllowGrayed プロパティの値は，チェックボックスが 2 つの状態になるか 3 つの状態になるかを示す。AllowGrayed が False (デフォルト) の場合，チェックボックスをクリックすると，チェックマークが付くか付かないかのどちらかの状態になる。AllowGrayed が True の場合は，チェックボックスをクリックすると，チェックマークが付く，淡色表示される，またはチェックマークが付かない，のいずれかになる

State プロパティは，チェックボックスコントロールの状態を決める。cbUnchecked は，チェックボックスにチェックマークが付かず，ユーザーがそのオプションを選択していないことを示す。cbChecked は，チェックマークが付いていて，ユーザーがそのオプションを選択していることを示す。cbGrayed は，チェックボックスが淡色表示されていて，チェックマーク付きでもなしでもない第 3 の状態であることを示す。淡色表示されたチェックボックスの意味は，アプリケーションで決定する

RadioButton1078035

ラジオボタンは，相互に排他的な（同時に 1 つしか選べない）選択肢の集合です。ラジオボタンコンポーネントを使用すると個別のボタンを配置することができ，ラジオグループコンポーネントを使用すると Caption プロパティを持つ長方形の領域を設定して，Items プロパティを使ってラジオボタン項目を列挙することができます。詳細については「コンポーネントのグループ化」を参照してください。

ラジオボタンの値を設定するには，Caption プロパティを使う

Checked が True の場合，ラジオボタン内にそのオプションが選択されたことを示す黒い丸が表示される

Tool bars1078036

ツールバーを使うと，ビジュアルコントロールの配置と管理を行うことができます。ツールバーはパネルコンポーネントとスピードボタンから作成することができ，ToolBar コンポーネントを使って，配置したい各ボタンのスピードメニューで［新規ボタン］を選択して作成することもできます。後者の方法には次のような利点があります。

ツールバーのすべてのツールボタンの幅と高さを統一して管理できる

ツールバーに配置する他のコントロールは不可視のツールボタンによって保持され，統一した高さで管理できる

コントロールがツールバーの横幅に収まらない場合は自動的に次の行に折り返される

スペースとディバイダ（特別に設定されたツールボタン）を使ってツールバーのコントロールをグループ化できる

ポップアップ境界や透過性などの表示オプションを追加できる

フォームにツールバーを追加する方法については「ツールバーとクールバーの使い方」で説明しています。

Cool bars1078037

クールバーには，個別に移動とサイズ変更が行える子コントロールが配置されます。各コントロールはそれぞれのバンド上に常駐します。ユーザーは，各バンドの左側のサイズ変更グリップをドラッグして位置を設定できます。

クールバーを使用するためには，設計時および実行時にバージョン 4.70 以上のCOMCTL32.DLL（通常は WINDOWS\SYSTEM または WINDOWS\SYSTEM32 ディレクトリに格納されている）が必要です。

Bands プロパティは TCoolBand オブジェクトの集合を保持する。設計時には，バンドエディタを使ってバンドの追加，削除，変更が行える。バンドエディタを開くには，オブジェクトインスペクタで Bands プロパティを選択して右側の欄をダブルクリックするか，省略記号（...）ボタンをクリックする。バンドの作成は，単にパレットから新しいウィンドウコントロールを追加することによっても行える

FixedOrder プロパティを True または False に設定することで，ユーザーがバンドの順序を変更できるかどうを指定できる

FixedSize プロパティを使うと，バンドを統一された高さと幅で管理するかどうかを指定できる


Handling lists
Handling lists1078038

Section topics	参照

リストは，選択する項目の集合をユーザーに表示します。リストを表示するコンポーネントは以下のとおりです。

コンポーネント	用途
ListBox	テキスト文字列のリストを表示する。ユーザーは，1 つまたは複数のテキスト文字列を選択できる
ComboBox	折りたためるテキスト文字列リストを表示する。このコンポーネントはフォーム領域を節約する
TreeView	項目を階層的に表示する
ListView	項目をグラフィック表示する
ImageList	イメージリストを管理する
CheckListBox	各項目の前にチェックボックスの付いたリストを表示する
DateTimePicker	日付または時刻入力用のリストボックスを表示する
Properties common to list controls1078039

以下のプロパティは，リストコントロールの表示に共通のプロパティです。

リストコントロールで列の数を指定するには Columns を使う

リストボックスが垂直のスペースに完全に合う項目だけを表示するかどうかを指定するには IntegralHeight を使う。IntegralHeight が False の場合，リストボックスの下端は ItemHeight プロパティが決めた位置となり，一番下の項目はリストに表示されないこともある

ピクセルでリスト項目の高さを指定するには ItemHeight を使う。Style プロパティを使うと，ItemHeight が無視されることがある

以下のプロパティはリストのコントロールに共通しています。

文字列リストを使ってリストコントロールに値を入れるには Items を使う。文字列リストの使い方については「文字列リストの操作」を参照

リストのどの項目を選択するか指定するには ItemIndex を使う

1度に複数の項目を選択できるか指定するには MultiSelect を使う。ユーザーは，〔Ctrl〕キーを使って連続しない複数の項目を選択するかまたは〔Shift〕キーを使って項目の範囲を選択できる

リストをアルファベット順に分類するか指定するには Sorted を使う

List boxes1078040

リストボックスは，ユーザーが 1 つまたは複数の項目を選択できるリストを表示します。リストボックスを使う場合に重要なプロパティは以下のとおりです。

リストボックス項目の追加，削除，挿入には，文字列リストである Items プロパティの Add，Delete，および Insert メソッドをそれぞれ使う

MultiSelect が True の場合，ユーザーは複数の項目を選択できる。デフォルトでは，リストボックスから複数選択するには，〔Ctrl〕キーを押しながら個々の項目をクリックする。〔Shift〕キーを押し続けても意味がない。〔Shift〕キーを使って値の範囲を選択するには，MultiSelect と ExtendedSelect の両方を True に設定する

Style プロパティは，リストボックスに項目を表示する方法を指定する。デフォルトは lbStandard であり，リストボックスの項目はそれぞれ文字列として表示される。Style の値を変更すると，オーナー描画リストボックスを作成できる。つまり，項目をグラフィックにしたり高さを一定または可変にしたりできる。
アプリケーションにオーナー描画コントロールを実装する例については「オーナー描画コントロールの作成」を参照

Combo boxes1078041

コンボボックスは編集ボックスとリストを結合したコントロールで，リストボックスによく似ています。ユーザーは編集ボックスにテキストを入力することも，リストの項目を選択することもできます。

テキストを入力するかリストの項目を選択してユーザーがコンボボックスにデータを入力すると，Text プロパティの値が変化する

デフォルトでは，ドロップダウンリストには 8 個の項目が表示される。表示する項目数を増減するには，DropDownCount に新しい値を割り当てる

コンボボックスには 5 種類のスタイルがあります。コンボボックスの種類を選択するには，Style プロパティを使います。

ユーザーがボタンを押したときだけリストボックスのような値リストを表示するには，csDropdown を使う。デフォルトでは，テキスト領域は編集可能である

コンボボックスの値を読み出し専用にするには csDropDownList スタイルを使う。ユーザーは項目の編集や新しい項目の入力ができない

リストがない編集ボックスを作成するには csSimple を使う

Tree views1078042

ツリービューコントロールは特殊なリストボックスで，オブジェクトの集合を，その論理的な階層関係に基づき，インデントして表示します。このコントロールには，アウトラインを展開したり折りたたむボタンがあります。ツリービューを使うと，コンテナや階層要素の関係をわかりやすく表示できます。

ツリーには，各項目のテキストラベルが付いたアイコンもオプションで入れられます。ユーザーがツリーの項目を展開したり折りたたんだときに，異なるアイコンの表示ができるようになります。グラフィック (チェックボックスなど) を入れて項目の状態情報を示すこともできます。

このコントロールはリスト項目の階層関係を定義する線や，アウトラインを展開または折りたたむためのボタンを描画することもできます。

Indent は親項目と項目を水平方向で分割するときの距離をピクセル数で設定する

項目を展開できることを示す［+］ボタンを削除するには，ShowButton を False に設定する

ツリービューの接続線を削除するには，ShowLines を False に設定する

ルート (最上位レベル) 項目を接続する線を削除するには，ShowRoot を False に設定する

DateTimePicker1078043

DateTimePicker は，日付または時刻を入力するためのリストボックスを表示します。DateTimePicker を使用するためには最新バージョンの COMCTL32.DLL（通常は WINDOWS\SYSTEM または WINDOWS\SYSTEM32 ディレクトリに格納されている）が必要です。


Grouping components
Grouping components1078044

Section topics	参照

情報をグループに分けて表示すると，ユーザーのアプリケーション間の移動がより簡単になります。Delphi には，情報をグループ化する以下のようなコンポーネントがあります。

コンポーネント	用途
GroupBox	タイトルが付いた標準のグループボックスを作成する
RadioGroup	ラジオボタンだけの単純なグループを作成する
Panel	視覚的に柔軟なコントロールグループを作成する
ScrollBox	コントロールを入れるスクロール可能領域を作成する
TabControl	互いに排他的なノートブックスタイルのタブを作成する
PageControl	互いに排他的なノートブックスタイルのタブとそれに対応するページを作成して各ページにほかのコントロールを入れる
HeaderControl	データ列にタイトルを付ける
Group boxes1078045

GroupBox コンポーネントは，Windows の標準グループボックスで，フォーム上の関連したコントロールをグループ化するのに使います。グループボックスの中に入れるもっとも一般的なコントロールは，ラジオボタンです。

グループボックスをフォームに追加してから，グループボックスに入れるコンポーネントをコンポーネントパレットから選択し，それをグループボックスに追加します。

グループを識別するテキストは Caption プロパティの値として表示されます。

Radio groups1078046

ラジオグループコンポーネントを使うと，ラジオボタンのグループ化とそのグループに協調動作をさせるタスクが簡略化されます。ラジオグループでは，Caption プロパティを持つ長方形の領域が提供されます。

ラジオグループコンポーネントの Items プロパティを使って，ボックス内の選択肢を指定する。オブジェクトインスペクタの［プロパティ］ページで省略記号（...）ボタンを選択すると文字列リストエディタが起動される。ラジオボタンの右側に表示させる文字列を入力して〔Enter〕を押す

ラジオグループコンポーネント内の個々のラジオボタンを選択することはできない。ボタンの間隔を変更するには，ラジオグループコンポーネントのサイズを変更する。名前を変更するには文字列リストエディタを使用する

Panels1078047

Panel コンポーネントは，フォームにほかのコントロールを追加できるパネルを追加するのに使います。たとえば，パネルを使ってツールバーを作成できます。パネルコンポーネントはコンテナです。視覚効果を高めるためには，代わりにべベルを使います。

フォームのサイズを変更してもフォームに対する相対的な位置が保たれるように，パネルはフォームと位置合わせできます。

BorderWidth プロパティはパネルの回りの境界の幅をピクセル数で指定する。デフォルト値は 0 であり，境界がないことを意味する

Locked プロパティはパネルをインプレースアクティブ OLE オブジェクトで置き換えするかどうかを指定する。Locked が False の場合，OLE サーバーはパネルを置き換えできる。Locked が True でパネルがフォームの辺のいずれかに位置合わせされている場合，OLE コンテナコンポーネントの OLE オブジェクトがインプレースアクティブになってもパネルはそのままである。ステータスバーなどが置き換えられるのを防ぐには Locked を使う

Page controls1078048

PageControl コンポーネントは，複数ページのダイアログボックスを作成するのに使うページセットです。設計時にページコントロールに新しいページを作成するには，ページコントロールを右クリックしてからスピードメニューの［ページ新規作成］を選択します。

ActivePage プロパティはアクティブなタブシートオブジェクトを指定する

複数行にするには Multiline を True に設定する

PageCount はページ数を指定する

Pages はタブシートオブジェクトのページをアクセスできるようにする

TabHeight プロパティはタブの高さをピクセル数で指定する。TabWidth は各タブの幅をピクセル数で指定する。TabWidth が 0 の場合，テキストに合わせてタブのサイズが自動的に決まる

Tab controls1078049

TabControl はノートブックの仕切りを表します。複数ページダイアログボックスを作成するには，ページコントロールを使います。タブコントロールは Delphi 1.0 の TabSet にかわるものです。

Scroll boxes1078050

ScrollBox は，フォーム全体よりも小さいスクロール領域をフォーム上に作成できるようにします。アプリケーションで特定の領域に収まりきれない情報を表示する必要がある場合はたくさんあります。リストボックスやメモなどのコントロールでは自動的に内容がスクロールしますが，他のコントロールの場合やフォームがコントロールでいっぱいの場合には，スクロールの機能を追加する必要があります。Delphi では，スクロールボックスというコントロールを使ってこのようなスクロール領域を扱います。

スクロールボックスはパネルやグループボックスと同じように中に他のコントロールを配置することができますが，スクロールボックス自体は通常は目に見えません。しかし，スクロールボックスの可視領域にすべてのコントロールを表示しきれない場合には，自動的に 1 つまたは 2 つのスクロールバーが表示され，ユーザーは可視領域に表示されていなかったコントロールを見える位置に移動して使用することができます。

スクロールする領域に対してスクロールボックスの境界を設定する

スクロールボックスのスクロールバーが水平であるか垂直であるか指定するには，Kind プロパティを使う

スクロールボックスの Align プロパティを使うと，スクロールボックスの領域をフォームまたはフォームの部分に対して調整できる

Header controls1078051

HeaderControl コンポーネントはテキストを表示するセクションに分かれたビジュアルコントロールで，各セクションはマウスでサイズ変更できます。設計時には，セクションの境界でマウスボタンをクリックしてドラッグすると新しいサイズに変更できます。実行時には，ユーザーが左マウスボタンでクリックしてドラッグするとヘッダーサイズを変更できます。サイズ変更しなかったセクションの幅は変わりません。

ヘッダー内の個々のセクションを指定するには Sections プロパティを使う

ヘッダーコントロールでは，ヘッダー部分の区切りをドラッグして各列の幅を設定することもできます。列の形式を整えるコマンド (列内の最大値に合わせて列サイズを自動変更するなど) のショートカットとして，区切りをダブルクリックできるようにするオプションもあります。


Visual feedback
Visual feedback1078052

Section topics	参照

適切に設計されたアプリケーションは，アプリケーションの現在の状態に関する情報をユーザーに提供します。この情報は以下のコンポーネントを使って表示されます。

コンポーネント	用途
Label	編集できないテキスト文字列を表示する
ProgressBar	特定の作業の進行状況（パーセンテージ）を表示する
StatusBar	編集できないステータス領域をウィンドウ下部に表示する
StaticText	編集できないテキストをウィンドウハンドルを持つコンポーネントに表示する
Hint と ShowHint	ヘルプヒントをアクティブにする
HelpContext	オンラインヘルプシステムにリンクする
Labels1078053

ラベルコンポーネントはフォーム上にテキストを表示します。通常は編集ボックスまたは他のコントロールの隣に追加されます。ラベルは非ウィンドウコントロールなので，フォーカスを受け取れません。

Caption はラベルのテキスト文字列を保持する

FocusControl プロパティはラベルコントロールをフォーム上の別のコントロールとリンクする。ラベルのキャプションにアクセラレータキーが含まれる場合，ユーザーがアクセラレータキーを使うと，FocusControl プロパティで指定されたコントロールにフォーカスが移動する

ラベルをグラフィックの上に表示し，グラフィックまたはビットマップの一部が隠れないようにラベルが透けて見えるようにするには，Transparent プロパティを True に設定する

ShowAccelChar プロパティは，& (アンド記号) をラベルのキャプションにどのように表示するかを決める。ShowAccelChar が True の場合，アンド記号はキャプション内のアンド記号の右側の文字の下線として表示され，下線付きの文字がアクセラレータ文字であることを示す。False の場合は，アンド記号はそのままアンド記号として表示される

Progress bars1078054

プログレスバーは，操作の進行状況を示すために使われるコントロールです。これは四角形のバーで，進行の度合いに応じて左から右に「満たされて」いきます。このコントロールは時間のかかる操作やバックグラウンド処理の進行状況をユーザーにフィードバックするために使います。

プログレスバーのデフォルト位置を設定するには Position を使う。実行時には進行状況に従って Position の値が変化して正確な位置を示す

Position の範囲を設定するには Max と Min を使う

デフォルトでは，進行メーターの値は 1 ずつ進む。単位量を増やすには StepBy に大きい値を割り当てる。詳細についてはオンラインヘルプの「StepIt メソッド」を参照


Status bars
Status bars1078055

Section topics	参照

ステータスバーは，通常はウィンドウの最下部に配置され，テキスト文字列を表示します。Delphi のパネルコンポーネントを使ってステータスバーを作成することもできますが，Windows のステータスバーコンポーネントを使った方が簡単です。一般にステータスバーは複数のテキスト領域に分割して使います。

ステータスバーコンポーネントでは，自動的に Align プロパティが alBottom に設定され，位置とサイズが管理される

ステータスコンポーネント内にサブパネルを作成するには Panels プロパティを使用する。オブジェクトインスペクタで省略記号（...）ボタンを選択するとパネルエディタが起動される

パネルエディタを開いてパネルエディタで各パネルを選択し，パネルの Width プロパティを設定する。同時に Alignment や他のプロパティも設定する

アプリケーションのステータスを表すように，各ステータスパネルにコードを追加する

Help or hint properties for a component1078056

以下のプロパティは，ヘルプとヒントを表示するすべてのコントロールに共通のプロパティです。

Hint プロパティは，マウスポインタをコントロールまたはメニュー項目に置いたときに表示できるテキスト文字列である。マウスをコンポーネントに合わせるとヒントが表示されるようにするには，ShowHint を True に設定する

ParentShowHint プロパティを使うと，グループ内のコントロールに定義されたすべてのヒントをすばやく表示できる。フォントや色の親プロパティと同様に，ParentShowHint プロパティはヒント表示の有無についてコントロールがどこを見ればよいかを決める

HelpContext プロパティはコントロールのヘルプコンテキスト番号を設定する


Tabular display
Tabular display1078057

Section topics	参照

グリッドは，セルの集合を定義する一連の行と列から構成される表です。セルに表示するものは，アプリケーションやグリッドコントロールの種類によって異なります。

コンポーネント	用途
DrawGrid	既存のデータ構造をグリッドに表示する
StringGrid	テキスト文字列のグリッドを表示する
DBGrid	データセットの内容を表示する
Draw grids1078058

描画グリッドは，既存のデータ構造を行列形式で表示するグリッドコントロールです。

グリッドはセルを描画するのに OnDrawCell イベントを使う。DefaultDrawing プロパティがFalseの場合，OnDrawCell イベントハンドラとして作成したコードがセルに描画される。DefaultDrawing が True の場合，セルの内容はデフォルト値を使って自動的に描画される

セルの描画領域を取得するには CellRect メソッドを使う。MouseToCell メソッドはマウスカーソルがあるセルの行列座標を返す

グリッドのどのセルが選択されているかを調べるには，Selection プロパティの値を使う

グリッドの外観と動作を変更するには，Options プロパティの値を変更する。たとえば，ユーザーが〔Tab〕を使って別の列へ移動できるようにしたり，列間にはグリッド線を表示するが行間には表示しないように決めたり，またグリッドに表示されたデータをユーザーが編集できるようにしたりできる

グリッドの外観に影響するプロパティはいくつかあり，DefaultColWidth と DefaultRowHeight プロパティはそれぞれ列の幅と行の高さのデフォルトを指定する

特定の列の幅や行の高さを変更するには，ColWidths プロパティと RowHeights プロパティを使う。行や列を固定したりスクロールしないようにするには FixedCols と FixedRows プロパティを使う。固定した行や列の色を指定するには FixedColor プロパティを使う。グリッド線の幅を設定するには GridLineWidth プロパティを使う。スクロールバーをグリッドに追加するには ScrollBars プロパティを使う

どの行が現在グリッドの最上行かを調べる場合や特定の行を最上行に設定する場合には，TopRow プロパティを使う。どの列がグリッドの最初に表示されているかを調べる場合は LeftCol プロパティを使う。VisibleColCount プロパティと VisibleRowCount プロパティの値は，それぞれグリッド内に表示する列と行の数を示す

以上のプロパティ，メソッド，イベントの他に，このコンポーネントにはすべてのウィンドウコントロールに適用されるプロパティ，メソッド，イベントもあります。

String grids1078059

文字列グリッドは，文字列と関連オブジェクトの処理を簡単にし，しかも描画グリッドのすべての機能を備えるように設計されているグリッドコントロールです。

文字列グリッドのすべての文字列は Cells プロパティに保持されている。このプロパティを使って，グリッド内の特定の文字列にアクセスできる。文字列グリッド内の文字列に関連するすべてのオブジェクトは Objects プロパティに保持されている

特定の列のすべての文字列とその関連オブジェクトは Cols プロパティを使ってアクセスできる。Rows プロパティは特定の行のすべての文字列とその関連オブジェクトにアクセスできるようにする

以上のプロパティ，メソッド，イベントの他に，このコンポーネントにはすべてのウィンドウコントロールに適用されるプロパティ，メソッド，イベントもあります。


Graphic display
Graphic display1078060

Section topics	参照

グラフィックを適切に使えば，装飾やスタイルの追加によってアプリケーションを目立たせることができます。Delphi アプリケーションにグラフィックを入れるのに使うコンポーネントは以下のとおりです。

コンポーネント	用途
Image	グラフィックファイルの内容を表示する
Shape	幾何学図形を表示する
Bevel	3 次元の線と枠を表示する
PaintBox	グラフィックをプログラムで表示する
Animate	AVI ファイルを音声なしで表示する
Images1078061

イメージコンポーネントはビットマップ，アイコン，メタファイルなどのグラフィックイメージをフォームに表示します。Delphi の IMAGES サブディレクトリには各種のイメージが収められています。イメージコンポーネントを設定するのに使う主なプロパティは以下のとおりです。

表示するイメージを選択するには，Picture プロパティをクリックする

デフォルトでは，イメージは Image コンポーネントの中央に配置される。左上にイメージを合わせるには Center を False に変更する

境界線と一緒にイメージを拡大/縮小するには，Stretch を True に変更する

Shapes1078062

図形コンポーネントはフォームに幾何学図形を表示します。非ウィンドウコンポーネントなので，ユーザーの入力は受け付けられません。

図形コントロールが表示する幾何学図形を決めるには，Shape プロパティを設定する

境界の色を変更するには BorderColor を使う

図形の色を追加したりパターンを追加するには，Brush プロパティを使う。ペイントする方法は，Brush オブジェクト内の 2 つのネストされたプロパティである Color と Style によって決まる

Bevels1078063

ベベルコンポーネントを使うと，ベベル線，ベベルボックス，ベベル枠をアプリケーションのフォームに追加できます。

パネルコンポーネントには，コントロールの境界線の隣に表示されるアウターベベルと，アウターベベルの内側に表示されるインナーベベルの 2 つのベベルがある。ベベルの表示形式 (なし，盛り上がる，へこむ) を決めるには BevelInner と BevelOuter を使う

BevelWidth プロパティは，パネルのインナーベベルとアウターベベルの幅をピクセルで指定する

Paint boxes1078064

ペイントボックスコンポーネントを使うと，特定の四角形の中でコードを使ってフォーム上に描画できます。ペイントボックスの境界より外側では描画できません。フォームにペイントボックスを追加すると，OnPaint イベントハンドラを使ってペイントボックスの Canvas に描画できます。

キャンバスへの描画方法については｢実行時のグラフィックの描画｣を参照してください。

Animation control1078065

アニメーションコンポーネントは，AVI（Audio Video Interleaved）クリップを音声なしで表示するウィンドウです。AVI クリップは，映画のような連続したビットマップフレームです。AVI クリップには音声も入っていますが，このコンポーネントでは画像の表示だけが可能です。使用するファイルは，圧縮のかかっていない AVI ファイルか，RLE（Run-Length Encoding）で圧縮された AVI クリップでなければなりません。アニメーションコンポーネントには以下のようなプロパティがあります。

ResHandle は，AVI クリップをリソースとして保持するモジュールの Windows ハンドル。実行時に，アニメーションリソースを含むモジュールのインスタンスハンドルまたはモジュールハンドルを ResHandle を設定する。ResHandle を設定したら，ResID または ResName プロパティを設定して，モジュール内のどのリソースをアニメーションコントロールで表示するかを指定する

AutoSize を True に設定すると，アニメーションコントロールのサイズが AVI クリップのフレームのサイズに調整される

StartFrame および StopFrame は，クリップの開始フレームと終了フレームを指定する

CommonAVI を設定すると，Shell32.DLL で提供される Windows のコモン AVI クリップの 1 つを表示できる

アニメーションの開始と中断は，Active プロパティを True または False に設定することにより指定し，再生する回数は Repetitions プロパティで指定する

Timers プロパティを使うと，タイマーを使ってフレームを表示できる。これは，音声トラックの再生などの他のアクションをアニメーションシーケンスに同期させるときに有用


Windows common dialog boxes
Windows common dialog boxes1078066

Section topics	参照

コンポーネントパレットの［Dialogs］ページにあるダイアログボックスコンポーネントを使うと，Windows のコモンダイアログボックスを Delphi のアプリケーションで使えます。コモンダイアログボックスは，使いやすく一貫性のあるインターフェースをすべての Windows ベースのアプリケーションに提供します。このインターフェースを使ってユーザーは，ファイルを開く，ファイルを保存する，ファイルを印刷するなどの共通のファイル操作を実行できます。

Execute メソッドが呼び出されると，各ダイアログボックスが表示されます。Execute は論理値を返します。つまり，ユーザーが［OK］を選択してダイアログボックス内の変更を受け入れた場合には，Execute は True を返します。ユーザーが［キャンセル］を選択して変更の反映も保存もしないでダイアログボックスを終了した場合には，Execute は False を返します。


Customizing the Component palette
Customizing the Component palette1078067

Section topics	参照

コンポーネントパレットに表示するコンポーネントと表示する順序を変更することができます。以下の操作が行えます。

コンポーネントの非表示，再構成，名前の変更

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

コンポーネントテンプレートの作成とパレットへの追加


Rearranging the Component palette
Rearranging the Component palette1078068

Section topics	参照

コンポーネントパレットのページの順序，およびページ上のコンポーネントの順序の変更は次のようにして行います。

1.	［コンポーネント(C)｜パレットの設定(C)］を選択します。あるいは［ツール(T)｜環境オプション(O)］で表示される［環境オプション］ダイアログボックスで［パレット］ページを選択します。

［パレット］ページにはパレットの各ページと，そのページに表示されるコンポーネントの一覧が表示されます。

2.	以下の操作が行えます。

ページの移動または名前の変更を行うには，［削除(D)］，［名称変更(R)］，あるいは上下の矢印ボタンを選択します (ページを削除する場合は，最初にそのページのコンポーネントを非表示にします。次に［ページ(P)］リストボックスでページを選択してから［削除(D)］を選択します)。

ページを追加するには［追加(A)］を選択します。

ページ内でのコンポーネントの順序を変更するには，ページを選択してから，移動するコンポーネントを選択し，［非表示(H)］または上下の矢印ボタンを選択します。

コンポーネントを別のページに移動するには，移動するコンポーネントが入っているページを選択します。［コンポーネント(C)］リストからコンポーネントを選択して，［ページ(P)］リストの移動先のページにドラッグします。

以前に非表示にしたコンポーネントを表示するには，［ページ(P)］リストで［すべて］を選択します。［コンポーネント(C)］リストを目的のボタンまでスクロールし，そのボタンを表示するページまでドラッグします。

3.	［OK］を選択します。


Adding components to Delphi
Adding components to Delphi1078069

Section topics	参照

Delphi 2.0 では IDE にコンポーネントを追加するには，それらを VCL に組み込んでカスタマイズしたライブラリファイルを開発する必要がありました。Delphi 3.0 では，設計時パッケージが使用できるので，VCL を再コンパイルする必要はありません。

独自に開発したコンポーネントパッケージやサードパーティ製のコンポーネントパッケージをインストールすることができます。それには，［プロジェクト(P)｜オプション(O)］の［プロジェクトオプション］ダイアログボックスで，プロジェクトで使用するすべてのパッケージを指定します。

新しいコンポーネント用のデフォルトのコンテナとして設計時パッケージ DCLUSR30 が用意されています。

メモ	独自のコンポーネントを記述するためには，既存のコンポーネントを使う場合に比べて，Object Pascal とオブジェクト指向プログラミングについての深い知識が必要になります。コンポーネント開発のプロセスについては『開発者ガイド』で解説しています。

Installing component packages1078070

Delphi IDE にインストールするコンポーネントはパッケージに格納されていなければなりません (「パッケージの作成と編集」を参照)。コンポーネントのソースコードが入っているユニットファイルは，『開発者ガイド』で説明されているコンポーネントソースファイルのモデルに従っていなければなりません。

独自のコンポーネントやサードパーティ製のコンポーネントのインストールまたはアンインストールは，以下の手順に従って行います。

1.	必要なファイルをローカルディレクトリにコピーまたは移動します。

パッケージが .DPL，.DCP，.DCU ファイルに分かれている場合には，必ずそのすべてをコピーしてください (.DCP および .DCU ファイルについての詳細は「コンパイル成功時に作成されるパッケージファイル」を参照してください)。

パッケージが .DPC（パッケージコレクション）ファイルになっている場合は，その中に他の内容も含まれているので，.DPC ファイル 1 つをコピーするだけです (パッケージコレクションファイルについての詳細は「パッケージコレクションファイル」を参照してください)。

.DPC ファイルを（ファイルが分かれている場合は .DCU ファイルも）格納するディレクトリは，Delphi のライブラリパスに指定されているディレクトリでなければなりません。慣例上，実行形式ファイルは Delphi 3\BIN ディレクトリに格納されます。

2.	［コンポーネント(C)｜パッケージのインストール(P)］を選択します。あるいは，［プロジェクト(P)｜オプション(O)］を選択して［パッケージ］タブをクリックします。

3.	［設計パッケージ］の下に使用可能なパッケージの一覧が表示されます。

リストにパッケージを追加するには，［追加(A)］を選択して表示された［設計時パッケージの追加］ダイアログで，.DPL または .DPC ファイル（上記 1. を参照）が入っているディレクトリを探して［開く(O)］を選択します。.DPC ファイルを選択すると別のダイアログが表示され，パッケージコレクションから .DPL および他のファイルを抽出する操作が行えます。

パッケージをインストールするには，そのパッケージの隣りのチェックボックスを選択します。

パッケージをアンインストールするには，チェックボックスのチェックをはずします。

インストールされているパッケージに含まれるコンポーネントのリストを表示するには，そのパッケージを選択して［コンポーネント(C)］を選択します。

リストからパッケージを削除するには，そのパッケージを選択して［削除(R)］を選択します。

4.	［OK］を選択します。

パッケージ内のコンポーネントは，そのコンポーネントの RegisterComponents 手続きで指定されたコンポーネントパレットページに，RegisterComponents 手続きに与えられたのと同じ名前でインストールされます。

デフォルトの設定を変更していなければ，インストールされて使用可能なすべてのパッケージを使って新しいプロジェクトが作成されます。インストールの現在の選択内容を新しいプロジェクトの自動デフォルトとするためには，ダイアログボックスの一番下にある［デフォルト］チェックボックスにチェックを付けます。

Adding ActiveX controls1078071

Microsoft の仕様に従ったものであれば，ActiveX コントロールを Delphi のコンポーネントライブラリに追加することができます。これを行うには，追加したいコントロールの入った .OCX ファイルを指定します。Delphi は自動的にそのコントロール用の「ラッパー」ユニット（.PAS ファイル）を作成して，コントロールを認識可能なオブジェクトタイプにし，インストール済みユニットのリストに追加します。コントロールの名前，およびインストール先のパレットをページを指定することができます。

ActiveX コントロールをコンポーネントライブラリに追加する手順は次のとおりです。

1.	［コンポーネント(C)｜ActiveX コントロールの取り込み(R)］を選択します。

2.	さらに説明が必要な場合は，ダイアログボックスで［ヘルプ］ボタンを選択します。


Creating component templates
Creating component templates1078072

Section topics	参照

複数のコンポーネントから構成されるコンポーネントテンプレートを作成することができます。フォームにコンポーネントを配置して，それぞれのプロパティを設定し，必要なコードを記述したら，それらをコンポーネントテンプレートとして保存することができます。後でこのテンプレートをコンポーネントパレットから選択すれば，設定済みのコンポーネントのセットを 1 ステップでフォームに配置することができます。関連するプロパティとイベント処理のコードも同時にプロジェクトに追加されます。

テンプレートをフォームに配置した後は，各コンポーネントを 1 つずつ配置した場合と同じように，個別に位置を変えたり，プロパティを再設定したり，イベントハンドラを作成または変更したりすることができます。

コンポーネントテンプレートを作成する手順は次のとおりです。

1.	必要なコンポーネントをフォームの適切な位置に配置します。

2.	コンポーネントをすべて選択します。複数のコンポーネントを選択する一番簡単な方法は，マウスですべてを囲むようにドラッグすることです。選択した各コンポーネントの隅に灰色のハンドルが表示されます。

3.	［コンポーネント(C)｜コンポーネントテンプレートの作成(T)］を選択します。

4.	［コンポーネント名］編集ボックスに，コンポーネントテンプレートに付ける名前を指定します。デフォルトの名前として提示されるのは，上記 2. で選択した最初のコンポーネントのコンポーネント型の後に「Template」を付けたものです。たとえば最初にラベルを選択していた場合，提示される名前は TLabelTemplate になります。この名前は好きなように変更できます。ただし，既存のコンポーネント名と重複しないように注意してください。

5.	［パレットページ名］編集ボックスには，テンプレートを配置したいコンポーネントパレットのページを指定します。存在しないページを指定すると，テンプレートを保存するときに新しいページが作成されます。

6.	パレットに表示してテンプレートを表すビットマップを指定します。デフォルトのビットマップとして提示されるのは，上記 2. で選択した最初のコンポーネントのコンポーネント型で使われているビットマップです。他のビットマップを参照するには［変更(H)］を選択します。ビットマップのサイズは 24×24 ピクセルを超えることはできません。

7.	［OK］を選択します。

コンポーネントパレットからコンポーネントテンプレートを削除するには，［コンポーネント(C)｜パレットの設定(C)］を選択します (「コンポーネントパレットの再構成」を参照)。


See also1078073

コンポーネントパレットについて

フォームファイル

プロジェクトへのフォームの追加

Delphi オブジェクトを使ったプログラミング

オブジェクトからのデータとコードの継承

コントロールに影響するフォームプロパティ

タブ順の設定

ドラッグアンドドロップ

テキストを使って作業する

さまざまなツールバーコントロール

クールバーコンポーネントの追加

文字列リストの操作

オーナー描画コントロールの作成

グリッドの操作

実行時のグラフィックの描画

Windows コモンダイアログボックスの使い方

カスタムダイアログボックスの作成

ActiveX コントロールの作成


Creating a user interface
Creating a user interface1079001

Section topics	参照

Delphi のアプリケーションユーザーインターフェースには，通常は複数のフォームが含まれます。ユーザーインターフェースの中心的なフォームはメインフォームであり，そのほかにダイアログボックス，二次ウィンドウなどのフォームがあります。

メインフォームをカスタマイズしたり，インターフェースの他の部分を構成するフォームを追加しカスタマイズして，アプリケーションを開発します。フォームをカスタマイズするには，フォームにコンポーネントを追加し，プロパティを設定します。さらに，ユーザーが実行時にアプリケーションを制御するためのメニューを作成します。

Delphi のオブジェクトリポジトリのオブジェクトの 1 つを使ってフォームを設計することもできるし，ユーザーが設計したフォームをオブジェクトリポジトリに追加して他のプロジェクトで再利用することもできます。また，メニューテンプレートをメニューの土台として使い，プログラミングのニーズに応じてメニューをカスタマイズすることもできます。

この章では以下について説明します。

プロジェクトへのフォームの追加

フォームでのコンポーネントの操作

コンポーネントのプロパティの設定

カスタムダイアログボックスの作成

実行時の自動作成順序の設定


Adding a form to a project
Adding a form to a project1079002

Section topics	参照

Delphi を初めて起動すると，単一の空白フォームから成る新規プロジェクトが開きます。このフォームをプロジェクトの開始点として使用することも，フォームとそのユニットを削除してウィザードを選択してフォームを新しく作成することもできます。また，別に利用できるフォームがある場合はそのフォームを選択することもできます。 オブジェクトリポジトリについての詳細は，「オブジェクトの共有」を参照してください。

ウィザードを使用，または別のフォームをプロジェクトに追加するには，［ファイル(F)｜新規作成(N)］を選択してください。図に示すような［新規作成］ダイアログボックスが開きます。1079003

オプションを以下に示します。

［フォーム］ページからフォームウィザードを使って，ユーザーの仕様でフォームを作成し，プロジェクトに追加する

デフォルトの新規フォームが定義されていて，それをプロジェクトに追加する場合，［新規作成］ページから［フォーム］アイコンを選択する(デフォルトの新規フォームは［オブジェクトリポジトリ］ダイアログボックスで定義される。このダイアログボックスを使っていつでもデフォルトフォームを変更できる)

オブジェクトリポジトリで利用できるその他のフォームがある場合は，［フォーム］ページからそのフォームのいずれか 1 つを選択してその使用方法を指定できる(［コピー(C)］，［継承(I)］，および［直接使用(U)］オプションの説明は「オブジェクトの共有」にある。または，ダイアログボックスの［ヘルプ］ボタンをクリックする)

オブジェクトリポジトリには，ウィザード，標準フォーム，任意のフォーム，ダイアログボックス，データモジュール，ユーザーが追加したプロジェクトなどが含まれます。これらはすべて［新規作成］ダイアログボックスに表示されます。また，ダイアログボックスは現在のプロジェクトのページを持ち，そこにプロジェクト内に存在するフォームを一覧表示します。この中のいずれかを選択することも，またはプロジェクトのフォームから機能を継承することもできます。この場合，作成するアプリケーションが基本的に類似したいくつかのフォームを持つときには，フォームの 1 つの形式を作成してから継承によってその他のフォームを作成できます。標準フォームに加えた変更内容は，継承されたフォームすべてに反映されます。

Delphi は，ユーザーが開いたプロジェクトに，選択されたフォームとその関連ユニットを追加します。これで，プロジェクトで他のフォームを使うようにこのフォームを使えます。つまり，このフォームのカスタマイズ，コンポーネントの追加，コーディングができるようになります。

選択する共有オプションによっては，変更内容がオブジェクトリポジトリの元の項目に影響することがあります。

メモ	プロジェクトを開かなくても，［ファイル(F)｜新規作成(N)］を選び，オブジェクトリポジトリからフォームを選ぶことができます。このとき，フォームのユニットファイルが参照ファイルとして開きます。この後にプロジェクトを開くか新規プロジェクトを作成した場合，開いていたテンプレートフォームはそのプロジェクトの一部にはなりません。これをプロジェクトの一部として保存するには，プロジェクトが開いているときに明示的に追加する必要があります。


Specifying a form as the project main form
Specifying a form as the project main form1079004

Section topics	参照

デフォルトでは，最初に作成してプロジェクトに保存したフォームがプロジェクトのメインフォームになります。メインフォームは実行時に最初に作成されます(フォームの作成順序についての詳細は，「フォームの自動作成順の指定」を参照してください)。プロジェクトにフォームを追加する場合，アプリケーションのメインフォームとして別のフォームを表示しなければならないときがあります。また，フォーム作成順序を変更しない限りアプリケーション実行時に最初に表示されるフォームがメインフォームになるので，実行時にメインフォームを簡単にテストできます。

プロジェクトのメインフォームを変更する手順は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選択して，［フォーム］ページを選びます。

2.	［メインフォーム(M)］コンボボックスでプロジェクトのメインフォームにするフォームを選択して［OK］を選びます。

ここでアプリケーションを実行すると，新しく選択されたメインフォームが表示されます。


Adding additional forms
Adding additional forms1079005

Section topics	参照

プロジェクトへのフォームの追加は，最初のフォームを追加した方法と同じです。［表示(V)｜プロジェクトマネージャ(P)］を選択すると，プロジェクトマネージャにプロジェクトのフォームおよび関連付けられたユニットすべてが一覧表示されます。


Linking forms
Linking forms1079006

Section topics	参照

プロジェクトへのフォームの追加はプロジェクトファイルにそのフォームへの参照を追加しますが，プロジェクト内のほかのユニットには追加しません。フォームへの参照を参照フォームのユニットファイルに追加しなければ，新しいフォームを参照するコードは記述できません。これをフォームリンクといいます。

フォームをリンクする一般的な理由は，そのフォームのコンポーネントへのアクセスが提供されるためです。たとえば，フォームリンクを使ってデータベース対応コンポーネントを持つフォームをデータモジュールのデータアクセスコンポーネントに接続して利用できるようにします。

フォームをリンクする手順は次のとおりです。

1.	別のフォームへの参照が必要なフォームを選択します。

2.	［ファイル(F)｜ユニットを使う(U)］を選択します。

3.	参照されるフォームのフォームユニット名を選択します。

4.	［OK］を選択します。

別のフォームにリンクすることは，フォームユニットの uses 節が別のフォームユニットへの参照を持つことを意味します。つまり，リンクされたフォームとそのコンポーネントはリンク側のフォームのスコープになります。スコープ，ユニット，および uses 節についての詳細は「Object Pascal コードの書き方」を参照してください。

Avoiding circular unit references1079007

2 つのフォームが相互に参照する必要がある場合，プログラムのコンパイル時に「循環参照」エラーが発生することがあります。このようなエラーを回避するには，以下に示すいずれかの方法に従ってください。

それぞれのユニットファイルの implementation 部にユニット識別子を持つ uses 節を置く(［ファイル(F)｜ユニットを使う(U)］と同じ)

片方は interface 部に，もう一方は implementation 部に uses 節を置く(別のフォームのユニット識別子をこのユニットの interface 部に置く必要はほとんどない)

両方のユニットファイルの interface 部の uses 節に入れないでください。入れると，コンパイル時に「循環参照」エラーが発生します。


Customizing a form component
Customizing a form component1079008

Section topics	参照

フォームには Height プロパティや Width プロパティなどのようにすべてのコンポーネントに共通のプロパティのほかに，フォームの外観や動作を制御できるユニークなプロパティも多数あります。すべてのコンポーネントに共通のプロパティと，その設定や読み込みの方法についての詳細は「コンポーネントについて」に記載されています。ここでは，フォームに固有のプロパティを紹介します。


Controlling form appearance
Controlling form appearance1079009

Section topics	参照

アプリケーションの実行時にフォームがどのように表示されるかは，いくつかのプロパティによって決まります。これらのプロパティについては，ヘルプ索引でプロパティ名を検索するか，オブジェクトインスペクタでプロパティを選択し，〔F1〕を押してオンラインヘルプの説明を参照してください。

図に単純な Delphi フォームとその表示プロパティを示します。例えば設計時に画面上でフォームをサイズ変更したりして表示プロパティのほとんどを設定しますが，オブジェクトインスペクタでプロパティを直接設定することもできます。1079010

BorderStyle などのように，プロパティによっては実行時のウィンドウの外観と動作の両方に影響するものがあります。たとえば BorderStyle プロパティを bsNone に設定すると，境界が見えないウィンドウが表示され，マウス操作で境界をドラッグしてウィンドウをサイズ変更することができなくなります。


Controlling form behavior
Controlling form behavior1079011

Section topics	参照

フォームのプロパティの多くは，ウィンドウの外観を変えることなく動作を変更し，また状態を反映します。共通のフォームプロパティには以下のものがあります。

ActiveControl はフォームを新たに表示するときにフォームのどのコントロールにフォーカスを渡すかを設定する。ウィンドウがアクティブな場合，ActiveControl は実際にフォーカスを受け取っているコントロールを示す

Position，WindowState，Scaled は，ウィンドウを画面に表示する方法を決める。Position は，設計時に指定した位置とサイズでウィンドウを表示するか，または実行時に Windows が推奨するサイズと位置で表示するかを決める。WindowState は，ウィンドウの実行時の初期状態を最小表示，最大表示，普通のいずれかに設定する。Scaled は，表示画面の解像度に基づき実行時のフォームのサイズを調整するかどうかを決める

ShowHint は，ユーザーがマウスをフォームの上に置いたときに，ヘルプやヒントを表示するかどうかを決める。表示するテキストは Hint プロパティで設定する

FormStyle は，MDI (マルチドキュメントインターフェース) の動作を制御する。Delphi のフォームは通常のウィンドウとしてのほかに，MDI フレームや MDI 子として機能できる。MDI アプリケーションの構築方法についての詳細は「MDI アプリケーションの作成」を参照

KeyPreview は，フォームがアクティブコントロールより先にキー入力を受け取り，フィルタリングや再入力ができるようにする

PrintScale は，フォームの Print メソッドがフォームイメージを欧文ピッチで印刷するか印刷ページに合わせて固定ピッチで印刷するかを決める


Form properties that show in controls
Form properties that show in controls1079012

Section topics	参照

フォームに設定するプロパティの多くは，そのフォームに追加するコントロールの類似したプロパティの設定にも影響します。これらのプロパティを使うと，ウィンドウ内のすべてのコントロールのフォントや色などの属性を一括して設定できます。

このようにコントロールに「共通して影響」できるプロパティには，Color，Ctrl3D，Font，ShowHint があります。フォームに追加するビジュアルコンポーネントには，独自の Color，Ctrl3D，Font，ShowHint がありますが，それぞれ対応した「親」プロパティ (ParentColor，ParentCtrl3D，ParentFont，および ParentShowHint と呼ばれる) があります (ビジュアルコントロールを含むコンポーネントが親コンポーネントです。たいていはフォームですが，グループボックスやパネルコンポーネントのこともあります)。これらの「親」プロパティが True ならば，コントロールのプロパティは親プロパティの値を継承します。コントロールの対応するプロパティのいずれかを変更すると，親プロパティが無効になり設定した値が使われます。.


Manipulating components in forms
Manipulating components in forms1079013

Section topics	参照

GUI (グラフィカルユーザーインターフェース) 環境でコントロールを使ったことがあるならば，ここで説明する操作の大部分に慣れていることでしょう。この節では，以下の内容を解説します。

フォームへのコンポーネントの追加

フォームのコンポーネントの選択

コンポーネントのグループ化

コンポーネントの切り取り，コピー，貼り付け

コンポーネントの削除と復元

コンポーネントの位置合わせ

メモ	ここで解説する作業の多くは，キーボードでも行えます。キーボードの使い方についての詳細は，オンラインヘルプ索引で「キーボードショートカット」を検索して，トピックリストから「フォームのキーボードショートカット」を選択して参照してください。


Adding components to the form
Adding components to the form1079014

Section topics	参照

フォームにコンポーネントを追加する場合，デフォルトのコンポーネントサイズのままにすることも，サイズを変更することもできます。また，同じコンポーネントの複数のコピーも簡単に追加できます。

フォームの中央にコンポーネントを追加する手順は次のとおりです。

コンポーネントパレット内のコンポーネントをダブルクリックする
フォームに既にコンポーネントがある場合，追加したコンポーネントはオフセット (右下) され，残りのコンポーネントが部分的に見えなくなります

フォームの特定の場所にコンポーネントを追加する手順は次のとおりです。

1.	追加するコンポーネントをコンポーネントパレットでクリックします。

2.	フォームに追加するコンポーネントの左上隅となる場所にポインタを移動し，フォームをクリックします。
コンポーネントは，フォームをクリックした場所にデフォルトのサイズで表示されます。

フォームにコンポーネントを追加すると，Delphi はコンポーネントのインスタンス変数またはフィールドを生成し，これをフォームの型宣言に追加します。

type

  TAboutBox = class(TForm)

    BitBtn1: TBitBtn;	{ Delphi が追加したコード )

  end;	{ 簡単にするため一部の追加コードは省略 }

同じように，コンポーネントを削除すると対応する型宣言も削除されます。詳細は「イベントハンドラの削除」を参照してください。

Adding multiple copies of a component1079015

同じコンポーネントの複数のコピーをフォームに追加する手順は次のとおりです。

1.	〔Shift〕キーを押したままにします。

2.	追加するコンポーネントをコンポーネントパレットでクリックし，〔Shift〕キーを放します (コンポーネントを選択した後は〔Shift〕キーを押し続ける必要はありません)。

ポインタアイコンをクリックするとコンポーネントの選択が解除されます。

Sizing a component as you add it1079016

コンポーネントはフォームに追加した後でサイズ変更したり移動したりできますが，追加時にもサイズ変更できます。

コンポーネントを追加時にサイズ変更する手順は次のとおりです。

1.	追加するコンポーネントをコンポーネントパレットから選択します。

2.	コンポーネントを追加するフォーム上の位置にカーソルを移動し，マウスボタンを押したままマウスポインタをドラッグします。

3.	ドラッグ中，コントロールの位置とサイズを示すアウトライン (輪郭) が表示されます。

希望どおりのサイズになったら，マウスボタンを放します。


Selecting components in the form
Selecting components in the form1079017

Section topics	参照

フォームでコンポーネントを選択する方法はいくつかあります。Panel や GroupBox などのようにほかのコンポーネント内に取り込まれているコンポーネントも，ほとんど同じ方法で選択できます。

単一のコンポーネントを選択するには，次のいずれかの方法を使います。

フォーム上のコンポーネントをクリックする

オブジェクトインスペクタの上部にあるドロップダウンリストから選択する

選択したいコンポーネントがあるフォームで，〔Tab〕キーを使ってコンポーネントを選択する

複数のコンポーネントを選択することもできます。複数のコンポーネントを選択する方法は，コンテナコンポーネントやそれに入れられるコンポーネントも含めて，フォーム内のすべてのコンポーネントに適用できます。ただし，フォーム自体を選択しているときは，ほかのコンポーネントを一緒に選択することはできません。

複数のコンポーネントを選択するには，次のいずれかの方法を使います。

〔Shift〕を押しながらコンポーネントを1つずつクリックする

フォームの 1 箇所をクリックし，さらに選択するコンポーネントを包むようにドラッグする (ただし，Panel や GroupBox などに入っているコンポーネントを選択する場合は，〔Ctrl〕を押しながらドラッグする)
ドラッグして囲んだコンポーネントの回りには点線の四角形が表示されます。すべての選択するコンポーネントを四角形で囲んだら，マウスボタンを放します。なお，四角形で囲みやすいように，コンポーネントの配置をあらかじめ変えておく必要があることもあります。

フォーム内のすべてのコンポーネントを選択するには次のようにします。

［編集(E)｜すべて選択］を選択する

Resizing selected components1079018

フォーム上でコンポーネントを選択すると，サイズ変更ハンドルと呼ばれる小さな四角が，コンポーネントの縁に表示されます。1 つまたは複数のコンポーネントのサイズを変更するにはこのハンドルを使います。

単一のコンポーネントをサイズ変更する手順は次のとおりです。

1.	フォームでこのコンポーネントを選択します。

2.	サイズ変更ハンドルをドラッグして希望の大きさにします。マウスボタンを放すと，コンポーネントは新しいサイズで表示されます。

複数のコンポーネントをサイズ変更する手順は次のとおりです。

1.	サイズ変更するすべてのコンポーネントを選択します。

2.	［編集(E)｜サイズ(S)］を選択して，［サイズ］ダイアログボックスを表示します。

3.	サイズ変更オプションを選んでから，［OK］を選択します。


Grouping components
Grouping components1079019

Section topics	参照

ほかのコンポーネントを入れることのできるコンポーネントとしては，Delphi では Form のほかに GroupBox，Panel，Notebook，PageControl，ScrollBox などがあります。このような種類はコンテナコンポーネントと呼ばれています。このコンテナコンポーネントを使ってほかの複数のコンポーネントをグループ化すると，グループ化されたコンポーネントは設計時のユニットのように動作するようになります。たとえば，スピードボタンやチェックボックスなどをグループ化し，関連するオプションをユーザーに提供することができます。Panel コンポーネントのようなコンテナコンポーネントを使って，カスタマイズしたツールバー，バックドロップ，ステータスバーなども作成できます。

ツールバーの作成方法についての詳細は，「ツールバーとクールバーの使い方」を参照するか，またはオンラインヘルプ索引で「ツールバー」を検索してください。

コンテナコンポーネント内にコンポーネントを追加すると，コンテナと追加されたコンポーネントの間に新しい親子関係が成立します。「コンテナ」コンポーネント (親) を設計時に移動，コピー，削除すると，その操作はコンテナ内のコンポーネント (子) にも影響します。

メモ	コンポーネントと別のコンポーネントの間に親子関係が成立した場合でも，すべてのコンポーネントのオーナーはフォームです。コンポーネントの親とオーナーの違いについての詳細は，オンラインヘルプの「Owner プロパティ」と「Parent プロパティ」を参照してください。

通常は，コンテナコンポーネントを先にフォームに追加し，その後でコンテナに入れるコンポーネント群を追加します。この方が，グループ化したいコンポーネントをコンポーネントパレットからコンテナコンポーネントに直接追加できるので簡単です。

フォームにコンポーネントを追加したら，これを切り取って貼り付ければコンテナコンポーネントに入れることができます。

コンポーネント群をコンテナに入れる手順は次のとおりです。

1.	フォームに GroupBox コンポーネントまたは Panel コンポーネントを追加します。

2.	コンテナコンポーネントを選択している状態で，これに入れるコンポーネント群を通常と同じ方法で追加します。
追加したコンポーネント群はコンテナコンポーネント内に表示されます。

パレットでコンポーネントをダブルクリックすると，このコンポーネントはフォームかフォーム内のコンテナコンポーネントのうちどちらかフォーカスのある方に追加されます。なお，コンポーネントパレットでコンポーネントを選択し，コンテナコンポーネント内をクリックしてコンポーネントを追加する限りは，コンテナをあらかじめ選択しておく必要はありません。

同じコンポーネントの複数のコピーをコンテナに追加する手順は次のとおりです。

1.	〔Shift〕を押したままでパレットのコンポーネントを選択します。

2.	コンテナコンポーネント内をクリックします。
クリックするごとに，その位置に選択したコンポーネント (フォームも含む) のコピーが追加されます。

コンポーネントを追加し終わったらポインタアイコンを選択します。


Cutting, copying, and pasting components
Cutting, copying, and pasting components1079020

Section topics	参照

フォームとフォームの間やフォームとコンテナコンポーネント (Panel や GroupBox など) の間で，コンポーネントの切り取り，コピー，貼り付けができます。コンテナコンポーネントの場所は，コピー元のフォーム上でも別のフォーム内でもかまいません。

メモ	コンポーネントをコピーすると，コンポーネントのプロパティ設定やイベントハンドラへの関連付けもコピーされます。たとえば，あるボタンの Caption プロパティを Button1，イベントハンドラを TForm1.Button1Click とします。このボタンをコピーすると，同じ Caption プロパティと TForm1.Button1 のコードを呼び出す OnClick イベントハンドラを持つ別のボタンが作成されます。ただし，コピーしたボタンの名前は変更され，各ボタンは固有の名前を持つようになります。

すべての切り取り，コピー，貼り付けの操作には，以下の一般的規則が適用されます。

複数のコンポーネントを一括して切り取りまたはコピーできます。ただし，これは同一の親に属するコンポーネントに限ります。親はフォームでもフォーム内のコンテナコンポーネントでもかまいませんが，両方を同時に扱うことはできません。
親が異なるコンポーネントを個別に選択して切り取りまたはコピーしようとしても，実際に切り取りまたはコピーされるコンポーネントは，最初に選択したコンポーネントと同じ親に属するコンポーネントだけになります。たとえば，最初にフォームのボタンを 1 つ選択して，次に同じフォーム上のパネル内のチェックボックスを 1 つ選択し，2 つの選択したコンポーネントの切り取りやコピーをしようとしても，ボタンだけが切り取りまたはコピーされます。

1 つまたは複数のコンポーネントを貼り付けると，フォームとコンテナのどちらか選択されている方に表示されます。

コンポーネントの切り取り，コピー，貼り付けを行う場合，関連するイベントハンドラのコードが複製されるのではなく，コピーされたコンポーネントが元のイベントハンドラへ関連付けられます。

1 つまたは複数のコンポーネントをクリップボードに切り取りまたはコピーするには，次のようにします。

1.	コンポーネント (1 つまたは複数) を選択します。

2.	［編集(E)｜切り取り(T)］を選択してコンポーネントを現在の場所からクリップボードに移動します。または，［編集(E)｜コピー(C)］を選択してコンポーネントのコピーをクリップボードに追加します。

あらかじめ切り取りまたはコピーした 1 つまたは複数のコンポーネントを貼り付けるには次のようにします。

1.	コンポーネントを貼り付ける先のフォームまたはコンテナコンポーネントを選択します。

2.	［編集(E)｜貼り付け(P)］を選択します。


Deleting and restoring components
Deleting and restoring components1079021

Section topics	参照

コンポーネントを削除する手順は次のとおりです。

1.	フォームでコンポーネントを選択します。

2.	〔Del〕を押すか［編集(E)｜削除(D)］を選択します。

削除したコンポーネントを復元するには次のようにします。

［編集(E)｜元に戻す(U)］を選択する
復元したコンポーネントは，削除する前と同じように表示されます。プロパティの設定やコードの作成などについてカスタマイズした内容も，削除する前のとおりに復元されます。

注意	［元に戻す(U)］は，以下の操作を行う前に選択しなければなりません。そうしないと，コンポーネントを復元できなくなります。


Aligning components
Aligning components1079022

Section topics	参照

コンポーネントは，フォームやほかのコンポーネントに合わせて位置を調整することができます。位置を調整したいコンポーネントを選択したら，位置合わせパレットまたは［位置合わせ］ダイアログボックスを使って，位置合わせを行います。複数のコンポーネントを一括して位置合わせする場合は，最初に選択したコンポーネントに合わせてほかのコンポーネントの位置が調整されます。

位置合わせパレットでコンポーネントの位置合わせを行う手順は次のとおりです。

1.	複数のコンポーネントを選択します。

2.	［表示(V)｜位置合わせパレット(A)］を選択します。
位置合わせパレットが表示されます。

3.	パレットの位置合わせアイコンを選択します。
コンポーネントを選択している限り，継続して位置合わせオプションを選択，変更できます。

［位置合わせ］ダイアログボックスを使って，コンポーネントの位置合わせを行う手順は次のとおりです。

1.	複数のコンポーネントを選択します。

2.	［編集(E)｜位置合わせ(A)］を選択します。
［位置合わせ］ダイアログボックスが表示されます。

3.	ダイアログボックスで希望のオプションを選択します。

4.	［OK］を選択して位置合わせを確定します。

コンポーネントが選択されている間は，続けて位置合わせオプションを選択したり変更できます。

位置合わせパレットと［位置合わせ］ダイアログボックスについての詳細は，オンラインヘルプを参照してください。

Using the form grid as an alignment guide1079023

フォームグリッドとは，設計時のフォームに表示される等間隔の格子点です。このグリッドを利用すると，コンポーネントをビジュアルに位置合わせできます。

グリッドと［編集(E)｜グリッドに合わせる(G)］オプションは，設計時にデフォルトで有効となります。これにより，各コンポーネントの左端と上端は常に最寄りのグリッド目盛りになります。また，このデフォルト設定を変えて，［編集(E)｜グリッドに合わせる(G)］オプションやグリッド自体を無効にすることもできます。また，グリッドの格子点の間隔も変更できます。

フォームグリッドのオプションを設定するには次のようにします。

1.	［ツール(T)｜環境オプション(O)］を選択し，［環境オプション］ダイアログボックスを開きます。

2.	［設定］ページで設定を変更します。

Locking the position of components1079024

フォーム上のコンポーネントの位置が確定したら，その後に間違えて移動してしまうことがないように，コンポーネントをロック (固定) します。

フォームでコンポーネントの位置をロックするには次のようにします。

Delphi のメニューバーで［編集(E)｜コントロールのロック(K)］を選択します


Setting component properties
Setting component properties1079025

Section topics	参照

この節では，設計時にコンポーネントのプロパティを設定するいくつかの方法を解説します。プロパティの値は，アプリケーションの実行中にも変更できます。この方法は「実行時のプロパティの設定」で解説します。

各コンポーネントのプロパティについての詳細は，オンラインヘルプで「コンポーネント」を検索するか，トピック「ビジュアルコンポーネントライブラリのコンポーネント」を参照し，そのプロパティを持つコンポーネントを選択します。または，フォームでコンポーネントを選択して〔F1〕を押す方法もあります。

メモ	パレットの［ActiveX］ページと［Samples］ページのコンポーネントはサンプルです。これらは Delphi VCL の一部ではなく，したがって Delphi の一部としてはマニュアルやヘルプでは解説されていません。1079026


How the Object Inspector displays properties
How the Object Inspector displays properties1079027

Section topics	参照

オブジェクトインスペクタでは，選択したコンポーネントに応じて表示されるプロパティ群が自動的に変化します。このようにオブジェクトインスペクタは，設計時にコンポーネントのプロパティを設定しやすくするための機能をいくつか備えています。

あるプロパティをオブジェクトインスペクタで選択すると，ほかのコンポーネントをフォームに追加，選択したとき，そのコンポーネントが同じプロパティをもっていれば，そのプロパティが選択されたままになります。この機能は，同じプロパティの値をコンポーネントごとに指定したいときに，プロパティを改めて選択する必要がないので便利です。
選択したコンポーネントが同じプロパティをもっていない場合は，Caption プロパティが選択されます。Caption プロパティを持たないコンポーネントでは，Name プロパティが選択されます。

フォームで複数のコンポーネントを選択すると，オブジェクトインスペクタは選択したコンポーネントのすべてに共通するプロパティを表示します。プロパティの値が各コンポーネントで異なる場合でも同様です。この場合，表示されるプロパティの値は，デフォルト値か最初に選択したコンポーネントの値になります。共通するプロパティの値をオブジェクトインスペクタで変更すると，選択したすべてのコンポーネントにおいて，そのプロパティの値が新しい値に変わります。
ただし，この機能には例外が 1 つあります。フォームで複数のコンポーネントを選択した場合，すべてのコンポーネントに Name プロパティがあるにもかかわらず，オブジェクトインスペクタには Name プロパティが表示されません。これは，フォームの各コンポーネントの Name プロパティの値は重複することがないためです。


Tab-jumping to property names in the Object Inspector
Tab-jumping to property names in the Object Inspector1079028

Section topics	参照

〔Tab〕を押すと，値列とプロパティ列の間で切り替わります。値列にいるときに (マウスでプロパティを選択したときのデフォルトの位置は値列)〔Tab〕を押すと，プロパティ列に移動します。

オブジェクトインスペクタ内でプロパティにすばやく移動する手順は次のとおりです。

1.	プロパティ列をアクティブにします (カーソルが値列にあるときに〔Tab〕を押すだけです)。

2.	移動したいプロパティの最初の文字を入力します。
カーソルはその文字で始まる最初のプロパティに移動します。

3.	プロパティの 2 番目の文字を入力します。希望のプロパティに移動するまで次の文字の入力を続けます。

ここで〔Tab〕を押して値列に移動し，値を入力します。


Displaying and setting shared properties
Displaying and setting shared properties1079029

Section topics	参照

共有プロパティに同じ値を設定するには，値をコンポーネントごとに設定する必要はありません。

共有プロパティを表示，変更する手順は次のとおりです。

1.	共有プロパティを設定する複数のコンポーネントをフォーム上で選択します。
オブジェクトインスペクタの［プロパティ］ページには，選択したコンポーネントに共通するプロパティだけが表示されます (ただし，例外として Name プロパティは表示されません)。

2.	コンポーネントを選択したままで，オブジェクトインスペクタを使ってプロパティを設定します。

設計時のプロパティの設定方法についての詳細は，オンラインヘルプの「プロパティの設定」を参照してください。


Using property editors
Using property editors1079030

Section topics	参照

オブジェクトインスペクタで設計時にプロパティを編集するときには，いくつかの方法があります。これまでこの章では，直接値を入力する方法と既存の値をドロップダウンリストから選択する方法を解説してきました。

このほかに，プロパティによっては，値列をダブルクリックするとプロパティを設定するダイアログボックスが表示されます。また，コンポーネントによっては，フォームでコンポーネントをダブルクリックするとこのダイアログボックスが表示されます。オブジェクトインスペクタでは，ダイアログボックスで編集できるプロパティの値列には，［...］が表示されます。

Example of a property editor1079031

Image コンポーネントを使って，ダイアログボックスプロパティエディタの例を示します。フォームで Image コンポーネントをダブルクリックすると，図のような［画像の設定］ダイアログボックスが表示されます。このダイアログボックスを使うとコンポーネントに表示するイメージを指定できます。1079032

このダイアログボックスを使って，コンポーネント内に表示したい画像を指定します。

そのほかの種類のプロパティエディタについての詳細は，オンラインヘルプのトピック「プロパティエディタ」を参照してください。


Setting properties at runtime
Setting properties at runtime1079033

Section topics	参照

設計時に設定できるプロパティは，コードを使って実行時にも設定できます。また，実行時にだけ変更できるプロパティもあり，これらを「実行時プロパティ」と呼びます。

設計時にオブジェクトインスペクタを使ってコンポーネントのプロパティを設定するには，次のようにします。

1.	コンポーネントを選択します。

2.	［プロパティ］ページでプロパティを選択します。

3.	このプロパティに新しい値を入力します。

実行中にプロパティを変更する手順も同じようなものです。つまり，ソースコードでコンポーネント，プロパティ，新しい値を指定します。実行中のプロパティの設定は，設計時の設定に上書きされます。

Using properties to customize forms at runtime1079034

ダイアログボックスなどのフォームを複数のプロジェクトで共有する場合，このフォームを設計時に変更すると，ほかのプロジェクトで矛盾を生じる危険性があります。これを避けるには，実行時にフォームのプロパティを変更するコードを記述します。

たとえば，［バージョン情報］ダイアログボックスのキャプションには，このボックスを使うプログラムの名前を付けます。同じ［バージョン情報］ダイアログボックスを複数のプロジェクトで同時に使う場合，ほかのアプリケーションではその名前を表示させたくありません。


Developing custom dialog boxes
Developing custom dialog boxes1079035

Section topics	参照

Windows ベースのアプリケーションとユーザーの間で対話を行うもっとも一般的な方法の一つは，ダイアログボックスを使用することです。ダイアログボックスはアプリケーションの情報を表示しますが，ほとんどの場合ユーザーからの入力を受け付けます。

設計済みの単純なダイアログボックスや［パスワードダイアログ］テンプレートなどのフォームのテンプレート化されたダイアログボックスとは別に，Delphiではコンポーネントとして完成されたダイアログボックスもあり，コンポーネントパレットの［Dialogs］ページに表示されています。Windows のコモンダイアログボックスをカプセル化したコンポーネントも含まれます。このようなダイアログボックスに対しては，ヘルプボタンを表示するかどうかというようなオプションを指定することはできますが，設計の大きな変更はできません。

当然ながら，独自のダイアログボックスを設計したい場合もあるはずです。このような場合，ダイアログボックスを「ゼロから」構築する方法を知っておくと便利です。この節では，以下のようなダイアログボックスを設計する場合に考慮すべき内容について説明します。

モード付きとモードなしのダイアログボックス

ダイアログボックスのためのフォームプロパティの設定

コマンドボタン

標準コマンドボタンの作成

タブ順の設定

タブ順のテスト

タブ順からのコンポーネントの削除

コンポーネントを使用可能または使用不可にする

ダイアログボックス中のフォーカスの設定


Making a dialog box modal or modeless
Making a dialog box modal or modeless1079036

Section topics	参照

設計時のダイアログボックスは，単純なカスタマイズされたフォームですが，実行時のダイアログボックスは「モード付き」か「モードなし」になります。モード付きで実行したフォームは明示的に閉じない限り，別の実行中のフォームでの作業を開始できません。ほとんどのダイアログボックスはモード付きです。

モードなしで実行しているフォームは，ユーザーが別のフォームで作業する間も画面に開いておくことができます (たとえば，アプリケーションのメインフォームはモードなしフォームです)。モードなしフォームは，たとえば，問い合わせ中に検索したレコード数や，ユーザーが作業中に参照する情報など，状態情報を表示するのに使用できます。

メモ	実行時にモードなしダイアログボックスをほかのウィンドウの手前に表示する場合は，FormStyle プロパティに fsStayOnTop を設定します。

フォームには実行時のモードを管理する 2 つのメソッドがあります。フォームをモードなしの状態で表示するにはフォームの Show メソッドを呼び出します。フォームをモード付きで表示するには，フォームの ShowModal メソッドを呼び出します。

次の 2 つの節では，Delphi の［バージョン情報］ボックスのフォームテンプレートを使用して，フォームの Show メソッドと ShowModal メソッドの使い方を示します。


Setting form properties for a dialog box
Setting form properties for a dialog box1079037

Section topics	参照

デフォルトのフォームには，アイコン化ボタン，最大表示ボタン，サイズ変更可能な境界があります。さらにフォームをサイズ変更するためのコマンドを提供するコントロールメニューもあります。これらの機能は実行時に，モードなしフォームには役立ちますが，モード付きダイアログボックスにはほとんど必要あありません。

モード付きダイアログボックスでは，フォームの BorderStyle プロパティに bsDialog を指定すると，以下のようなモード付きダイアログボックスの最も一般的な設定を行えるので便利です。

アイコン化ボタンと最大表示ボタンを削除する

［移動］と［終了］だけのコントロールメニューを設定する

フォーム境界をサイズ変更不可にし，ベベル表示にする

次の表にその他のフォームの設定を示します。このような設定を自由に組み合わせて使用することで，さまざまなフォームスタイルを作成できます。

プロパティ	設定	内容
BorderIcons
biSystemMenu	False	コントロール (システム) メニューの表示
biMinimize	False	アイコン化ボタンの表示
biMazimize	False	最大表示ボタンの表示
BorderStyle
	bsSizeable	フォームの境界をサイズ変更可能にする
	bsSingle	一本線のサイズ変更不可の境界を提供する
	bsNone	境界を表示せずサイズ変更不可
	bsDialog	境界表示し，サイズ変更不可のウィンドウ
	bsToolWindow	タイトルバーを最小化し，サイズ変更不可のウィンドウ
	bsSizeToolWindow	タイトルバーを最小化し，サイズ変更可能なウィンドウ
メモ	以上の設定を変更してもフォームの設計時の外観には影響しません。これらのプロパティ設定は実行時にのみ反映されます。


Providing command buttons
Providing command buttons1079038

Section topics	参照

ダイアログボックスには，ダイアログボックスをモード付きで使用するかモードなしで使用するかに応じて特定のコマンドボタンを用意します。モード付きダイアログボックスの場合，ユーザーにダイアログボックスを終了させる手段を提供しなければなりません。ダイアログボックスを終了する手段としては，1 つ以上のコマンドボタンを用意するのが標準的な設計です。メッセージボックスなどの単純なモード付きダイアログボックスでは，1 つのボタンで十分です。このボタンには［OK］や［終了］などのラベルを付けることができます (なお，次の段落で説明するようにダイアログボックスに［いいえ］というラベルのボタンがある場合は，最初のボタンに通常［はい］というラベルを付けます)。

ユーザーの入力を受け付けるダイアログボックスでは，入力を処理するかどうかをユーザーに選択させてからダイアログボックスを終了する場合があります。そのためには，［キャンセル］や［いいえ］などのラベルを付けたボタンを用意します (ダイアログボックスでユーザーに明示的に尋ねる場合は，このボタンのラベルを［いいえ］とします。そうでなければ［キャンセル］とする方が適切です)。

ユーザーがコマンドボタンを選択した場合に変更を実際に処理するかどうかは，コードで制御します。

Button コンポーネントのプロパティを設定すれば，ユーザーが〔Enter〕や〔Esc〕を押した場合に，ボタンのイベントハンドラコードを呼び出すか，それとも単にダイアログボックスを閉じるか，といったことを指定できます。この方法では，新たにコードを追加する必要はありません。

Executing button code on Esc1079039

Delphi ではボタン (Button) コンポーネントに Cancel プロパティを用意しています。フォームにあるボタンの Cancel プロパティに True を設定した場合，実行時に〔Esc〕が押されると OnClick イベントハンドラ内のコードが実行されます。

ボタンをキャンセルボタンとして設計するには次のようにします。

ボタンの Cancel プロパティに True を設定する

Executing button code on Enter1079040

ボタンには，Cancel プロパティと似た動作をする Default プロパティがあります。フォームにあるボタンの Default プロパティに True を設定した場合，実行時に〔Enter〕が押されるとボタンの OnClick イベントハンドラ内のコードが実行されます。ただし，〔Enter〕が押されたときフォーカスが別のボタンにある場合を除きます。

フォームにデフォルトボタンがあっても，実行時には別のボタンにフォーカスがある場合があります。この場合，〔Enter〕を押したときに呼び出されるのはフォーカスのあるボタンの OnClick イベントハンドラ内のコードで，ほかのボタンの Default プロパティ設定は無視されます (なお，ダイアログボックスでフォーカスのあるボタンは，ほかのボタンよりも太くて濃い境界で表示されます)。

メモ	フォームでどのコンポーネントにフォーカスがある場合でも，ユーザーが〔Enter〕を押したときに反応するのはボタンコンポーネントだけです。たとえば，フォームでボタン以外のコンポーネントにフォーカスがある場合に〔Enter〕が押されると，デフォルトボタンがOnClickイベントを受け取ります。その例については，「実行時のフォーカス設定」を参照してください。

ボタンをデフォルトボタンとして設計するには次のようにします。

ボタンの Default プロパティに True を設定する

実行時のフォーカスを変更するには次のようにします。

ボタンの SetFocus メソッドを呼び出す

詳細は「ダイアログボックス中のフォーカスの設定」を参照してください。

Closing a dialog box when the user chooses a button1079041

ユーザーがあるボタンを選択したときにモード付きダイアログボックスを自動的に閉じるには，そのボタンの ModalResult プロパティに 0 以外の値を設定します。ModalResult の値をそれぞれのボタンのキャプションに合わせて設定することにより，ユーザーの選択したボタンを特定することもできます。たとえば，［キャンセル］ボタンの ModalResult プロパティには mrCancel を設定し，［OK］ボタンの ModalResult には mrOK を設定します。どちらの ModalResult も 0 以外の値を ShowModal 関数に返すので，どちらのボタンが選択されてもフォームは閉じますが，ModalResult の返す値が mrCancel と mrOK のどちらであるかによって，選択されたボタンを区別することができます。

ユーザーが［キャンセル］ボタンを選択するか〔Esc〕を押したとき，ダイアログボックスを自動的に閉じるには次のようにします。

［キャンセル］ボタンの ModalResult プロパティに mrCancel を設定する

［OK］ボタンにフォーカスがあるときにユーザーが〔Enter〕を押した場合に，ダイアログボックスを自動的に閉じるには次のようにします。

ボタンの ModalResult プロパティに mrOK を設定する

「標準コマンドボタンの作成」では，ここで説明した［キャンセル］や［OK］ボタンなどの標準コマンドボタンを簡単に作成する方法を説明します。


Creating standard-command buttons
Creating standard-command buttons1079042

Section topics	参照

フォームにビットマップボタン (BitBtn) コンポーネントを追加して各ボタンの Kind プロパティを設定すると，多くの標準コマンドのボタンを簡単に作成できます。次の表に Kind プロパティの各設定と結果を示します (なお，ビットマップボタンはプロパティ設定によってさまざまなグラフィックを表示します。たとえば，［OK］ボタンには緑色のチェックマークを示し，［キャンセル］ボタンには赤色の×印を表示します)。

Kind の値	効果	表示	プロパティの設定	説明
bkAbort	［中止］をキャプションとするキャンセルボタンを作成する		Caption: = '中止(&A)' ModalResult: = mrAbort	キャプションの横に赤色の×印を表示する
bkAll	［すべて］をキャプションとする OK ボタンを作成する		Caption: = 'すべて' ModalResult: = 8	キャプションの横に緑色の二重のチェックマークを表示する
bkCancel	［キャンセル］ボタンを作成する		Caption: = 'キャンセル' Cancel: = True ModalResult: = mrCancel	キャプションの横に赤色の×印を表示する
bkClose	ウィンドウを閉じる［閉じる］ボタンを作成する		Caption: = '閉じる(&C)'	ボタンにラベンダー色の「出口」ドアを表示する
bkCustom	なし	なし	なし	この設定ではカスタムコマンドボタンを作成する。カスタムビットマップの指定を含む
bkHelp	［ヘルプ］をキャプションとするボタンを作成する		Caption: = 'ヘルプ(&H)'	キャプションの横に青色の ? 印を表示する。このボタンのイベントハンドラはプログラムのヘルプを呼び出す (この呼び出しはヘルプコンテキストのダイアログボックスでは自動的に行われる)
bkIgnore	［無視］をキャプションとするボタンを作成する		Caption: = '無視(&I)' ModalResult: = mrIgnore	エラー状態の発生後も操作を続行するのに使用する
bkNo	［いいえ］をキャプションとするキャンセルボタンを作成する		Caption: = 'いいえ(&N)' Cancle: = True ModalResult: = mrNo	キャプションの横に斜線入りの赤い円を表示する
bkOK	［OK］ボタンを作成する		Caption: = 'OK' Default: = True	キャプションの横に緑色のチェックマークを表示する
bkRetry	指定のアクションを再試行する［再試行］ボタンを作成する		Caption: = '再試行(&R)' ModalResult: = mrRetry	キャプションの横に緑色の円形矢印を表示する
bkYes	［はい］をキャプションとする OK ボタンを作成する		Caption: = 'はい(&Y)' Default: = True ModalResult: = mrYes	キャプションの横に緑色のチェックマークを表示する
すでに述べたように，Kind プロパティを設定すると ModalResult プロパティも設定することになります。ただし，bkCustom，bkHelp，bkClose は例外で，ModalResult の設定は mrNone のままです。したがってこのボタンを選択してもダイアログボックスが自動的に閉じることはありません。


Setting the tab order
Setting the tab order1079043

Section topics	参照

タブ順とは，実行中のアプリケーションで〔Tab〕を押してコンポーネントからコンポーネントへフォーカスを移行させる順序を意味します。〔Tab〕を使用してフォームのコンポーネントへフォーカスを移行させるには，コンポーネントの TabStop プロパティに True を設定します。

タブ順は，最初はフォームにコンポーネントを追加した順に従って設定されます。このタブ順を変更するには，各コンポーネントの TabOrder プロパティを変更するか，または［タブ順序の設定］ダイアログボックスを使用します。

［タブ順序の設定］ダイアログボックスを使用する手順は次のとおりです。

1.	タブ順を設定するコンポーネントのあるフォームまたはフォームのコンテナコンポーネントを選択します。

2.	［編集(E)｜タブ順序(R)］を選択するか，フォームのスピードメニューで［タブ順序(O)］を選択します。
［タブ順序の設定］ダイアログボックスが表示されます。このダイアログボックスには現在のタブ順に従ってコンポーネントが上から順に表示されます。

3.	［コントロールのタブ順一覧(C)］でコンポーネントを選択して，上矢印ボタンか下矢印ボタンを選びます。または，このコンポーネントをタブ順の新しい位置にドラッグします。

4.	［OK］を選択します。

［タブ順序の設定］ダイアログボックスでは，コンポーネントの TabOrder プロパティの値を変更します。この変更は手作業でもできます。

コンポーネントの TabOrder プロパティを手作業で変更する手順は次のとおりです。

1.	タブ順の位置を変更するコンポーネントを選択します。

2.	オブジェクトインスペクタで，TabOrder プロパティを選択します。

3.	コンポーネントを挿入するタブ順の位置に合わせて TabOrder プロパティの値を変更します。

メモ	タブ順の最初のコンポーネントに対しては TabOrder 値を 0 に設定します。

タブ順を手作業で設定する場合は以下の点に注意します (［タブ順序の設定］ダイアログボックスを使用する場合は注意の必要はありません)。

TabOrder プロパティの各値は重複してはなりません。あるコンポーネントに指定した TabOrder 値と同じ値を指定された別のコンポーネントが同一フォームにあると，Delphi はほかのすべてのコンポーネントの TabOrder の値を順に変更します。

フォームに存在するコンポーネント数と同じかそれ以上の数字を TabOrder 値に指定することはできません。そのような値を指定した場合，(番号付けは 0 から始めるため) Delphi ではコンポーネント数よりも 1 つ少ない値が代わりに指定され，タブ順の最後にそのコンポーネントが入れられます。

表示されないか使用不可にされたコンポーネントは，有効な TabOrder 値を持っていてもタブ順では認識されません。ユーザーが〔Tab〕を押しても，フォーカスはこのようなコンポーネントを飛び越して次ぎのタブ順にあるコンポーネントに移ります。詳細は「コンポーネントを使用可能または使用不可にする」を参照してください。


Testing the tab order
Testing the tab order1079044

Section topics	参照

設定したタブ順をテストするにはアプリケーションを実行します。設計時は，フォームにコンポーネントを追加した順にフォーカスが移行します。設計時に変更したタブ順は，実行時だけに反映されます。

タブ順をテストする手順は次のとおりです。

1.	アプリケーションを実行します。

2.	〔Tab〕を押して，フォーカスがコンポーネント間を移行する順番を確認します。


Removing a component from the tab order
Removing a component from the tab order1079045

Section topics	参照

フォームの特定のコンポーネントを〔Tab〕で移動できないようにしたい場合があるかもしれません。たとえば，ユーザーの変更できない Panel コンポーネントにユーザーをアクセスさせる必要はありません。このようなコンポーネントはタブ順から削除できます。実行中のアプリケーションでユーザーが〔Tab〕を押すと，フォーカスはこのコンポーネントを飛び越し，次のタブ順にあるコンポーネントに移行します。このコンポーネントに有効な TabOrder 値が設定されている場合も同様です。

タブ順からコンポーネントを削除する手順は次のとおりです。

1.	フォームでコンポーネントを選択します。

2.	オブジェクトインスペクタを使用して TabStop プロパティの値に False を設定します。

メモ	タブ順からコンポーネントを削除しても，コンポーネントは使用不可になりません。


Enabling and disabling components
Enabling and disabling components1079046

Section topics	参照

ダイアログボックスを最初に開いたときや，またはその後ダイアログボックスが実行時に一定の状態に変化したときに，ダイアログボックスやフォームの特定のコンポーネントをユーザーにアクセスさせたくない場合があります。たとえば，ファイルを処理するダイアログボックスでは，ファイル名が指定されない限り，［OK］ボタンを使用不可にすることがあります。

使用不可にしたコンポーネントは実行中のアプリケーションでは淡色表示になり，このコンポーネントの TabStop プロパティの値にTrueを設定していてもユーザーは〔Tab〕で移動できなくなります。

設計時にコンポーネントを使用不可にすると，ダイアログボックスを最初に開いたときに，ユーザーはそのコンポーネントを使用できません。しかし，コンポーネントは実行時に使用可能にすることができます。

設計時にコンポーネントを使用不可にするには次のようにします。

オブジェクトインスペクタでコンポーネントの Enabled プロパティに False を設定する

実行時にコンポーネントを使用不可にするには次のようにします。

コンポーネントのイベントハンドラに次のコードを入力する

<コンポーネント名>.Enabled := False;

たとえば次のイベントハンドラでは，Btton1 で OnClick イベントを受け取ったときに Button2 を使用不可にすることを指定しています。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Button2.Enabled := False;

end;


Setting the focus in a dialog box
Setting the focus in a dialog box1079047

Section topics	参照

実行中のアプリケーションでアクティブなコンポーネント，つまりフォーカスのあるコンポーネントは，1 つのフォームで同時に 1 つだけです。デフォルトでフォーカスを与えられるコンポーネントは，フォームの ActiveControl プロパティに対応しています。ActiveControlプロパティは設計時に設定することも，実行時にこのプロパティを使用してフォーカスのあるコンポーネントにアクセスすることもできます。なお，実行時にフォームを変更するには SetFocus メソッドを使用します。

Setting focus at design time1079048

通常，ダイアログボックスを設計する場合は，ダイアログボックスを最初に開いたときにフォーカスを与えるコンポーネントを指定しておきます。たとえば，データ入力用のフォームでは，ユーザーが最初にデータを入力する可能性の高い編集ボックスコンポーネントやメモコンポーネントにフォーカスを与えておき，ユーザーがすぐに入力を始められるようにします。

アクティブにするコンポーネントを設計時に指定する手順は次のとおりです。

1.	フォームを選択し，次にオブジェクトインスペクタを使用してフォームの ActiveControl プロパティを選択します。

2.	プロパティのドロップダウンリストで，フォームを最初に開いたときにフォーカスを与えるコンポーネントを選択します。

フォームの中でアクティブにするコンポーネントを指定しないと，タブ順の最初にあるコンポーネントに最初のフォーカスが与えられます。ただし，以下のコンポーネントは除きます。

使用不可のコンポーネント

実行時に表示されないコンポーネント

TabStop プロパティに False を設定したコンポーネント

Setting focus at runtime1079049

ユーザーが実行時にコンポーネント間を〔Tab〕で移動すると，フォーカスは自動的に移行します。しかし，場合によってはフォーカスを特定の方法で移行させたいことがあります。たとえば，データ入力用のフォームで，ユーザーが矢印キーを押すごとにフォーカスを入力フィールドから入力フィールドへ移動させるような場合です。コンポーネントにフォーカスを与えることを指定するには SetFocus メソッドを使用します。

実行時にアクティブコンポーネントを変更するには次のようにします。

対応するイベントハンドラに次のコードを入力する。この例では，コンポーネント名として Button1 を使っている

Button1.SetFocus;

詳細はオンラインヘルプで SetFocus メソッドの説明を参照してください。

メモ	設計時にフォームのアクティブコントロールとしてボタンを設定すると，すでに指定したデフォルトボタンを実行時に無視します。しかし，アクティブコントロールとデフォルトボタンを一緒に使用してユーザー入力を処理できる場合も多くあります。


Using dialog box routines
Using dialog box routines1079050

Section topics	参照

Delphi の Dialogs ユニットには，指定されたパラメータに応じて設計済みのダイアログボックスを表示する単純なルーチンがいくつかあります。

この節では，このようなルーチンを使って以下のことをする方法について説明します。

メッセージボックスの表示

単純な入力フォームの作成

入力文字のマスク


Displaying message boxes
Displaying message boxes1079051

Section topics	参照

メッセージボックスはユーザーにテキストを表示します。アプリケーションを続行するには，メッセージボックスを手動で画面から消去しなければなりません。メッセージボックスは以下の目的で使用します。

ユーザーへの警告情報の表示

エラーメッセージの表示

ファイルを閉じる前またはアプリケーションを終了する前の確認要求

ShowMessage procedure1079052

ShowMessage 手続きは，ユーザーに単純なメッセージを表示するもっとも簡単な方法です。この手続きの構文は次のとおりです。

ShowMessage(const Msg: string);

この手続きで表示されるモード付きダイアログボックスには，Msg パラメーターで指定したテキストと，このダイアログボックスを閉じるための［OK］ボタンがあります。

たとえば，ShowMessage 手続きを使ってメッセージボックスに Delphi のメッセージを表示するには，ボタンの OnClick イベントハンドラに次のコードを書き込みます。

ShowMessage('Delphi delivers!');

プログラムを実行してボタンをクリックすると，モード付きダイアログボックスが表示されます。次の図に示すようにタイトルバーには実行形式ファイルの名前が示され，さらに Msg パラメータのテキストと［OK］ボタンもダイアログボックスに表示されます。

MessageDlg function1079053

MessageDlg 関数で表示されるメッセージボックスには，指定したテキストのほかに，オプションとして各種のキャプション，シンボル，ボタンが示されます。

この関数の構文は次のとおりです。

function MessageDlg(const Msg: string; AType: TMsgDlgType; AButtons: TMsgDlgButtons;

  HelpCtx: LongInt): Word;

次の表に各パラメータで指定する内容を示します。各パラメータについての詳細は，オンラインヘルプを参照してください。

パラメータ名	内容	説明
Msg	ダイアログボックスに表示されるテキスト	このパラメータを省略した場合，ダイアログボックスにテキストは表示されない
Atype	ダイアログボックスのタイトルバーのキャプションと，それに付随するシンボル	このパラメータを省略した場合，メッセージボックスのタイトルバ一にキャプションは表示されない
Abuttons	ダイアログボックスのボタンの種類	このパラメータを省略した場合，ダイアログボックスにボタンは表示されない
HelpCtx	へルプトピックへのリンク	省略可能
HelpCtx パラメータには必ず整数を渡します。ヘルプファイルがない場合は 0 を渡します。へルプファイルを使うアプリケーションでは，ダイアログボックスに［ヘルプ］ボタンを追加し，このダイアログボックスでユーザーに表示するトピックに対応したへルプコンテキスト番号を渡します。無効なへルプコンテキスト番号を渡すと，ユーザーが［ヘルプ］ボタンを選択したときにエラーメッセージが表示されます。

アプリケーションとへルプシステムを連動させる方法についての詳細は，「［アプリケーション］オプション」を参照してください。

MessageDlg example1079054

ダイアログボックスに［変更を保存しますか］というメッセージと，［はい］，［いいえ］，［キャンセル］ボタンを作成するには，このイベントハンドラにボタンを追加します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  MessageDlg('変更を保存しますか', mtConfirmation, mbYesNoCancel, 0);

end;

プログラムを実行してボタンをクリックすると，次のメッセージボックスが表示されます。

メモ	MessageDlg はメッセージボックスをデフォルトで画面の中央に表示します。メッセージボックスを画面の指定位置に表示するには MessageDlgPos 関数を使います。

MessageDlg と MessageDlgPos についての詳細は，オンラィンヘルプのヘルプトピック「メッセージ」を参照してください。


Creating simple input forms
Creating simple input forms1079055

Section topics	参照

MessageDlg は，ユーザーのボタンクリックだけを要求する情報フォームを表示します。一方 Dialogs ユニットが提供する lnputBox と InputQuery の 2 つの関数は，ユーザーから 1 行の入力を要求するフォームを表示します。たとえば，パスワード入力画面などのフォームです。

lnputBox と InputQuery の構文は次のとおりです。

function InputBox(const ACaption, APrompt, ADefault: string): string;

function InputQuery(const ACaption, APrompt: string; var Value: string): Boolean;

lnputBox と InputQuery はどちらも［OK］ボタンと［キャンセル］ボタンの付いたダイアログボックスを作成します。lnputBox は，ユーザーが［OK］を選択した場合にユーザーの人力文字列を返します。ユーザーが［キャンセル］を選択するか〔Esc〕を押してダイアログボックスを終了した場合は，ユーザーの入力を返しません。lnputQuery は，ユーザーの操作 (［OK］，［キャンセル］，〔Esc〕) をプログラムで認識できる論理変数に変換します。

InputBox の使い方の例として，Button1 と Label1 コンポーネントを持つフォームで Button1 に対して次のような OnClick イベントハンドラを作成します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Label1.Caption := InputBox('Password Entry Form', 'Enter Password', '')

end;

Adefault パラメータ文字列を指定していないので，入力ボックスに最初は何も表示されません。

プログラムを実行して Button1 を選択すると，入力ボックスが表示されます。

入力ボックスに適当な文字列を入力して，［OK］を選択すると，Label1 に文字列が表示されます。ただし，［キャンセル］を選択するか〔Esc〕を押してダイアログボックスを終了した場合には，Label1 には入力した文字列が表示されません。この場合，ADefault 文字列が返されます。ADefault 文字列は空白なので，Label1 の Caption プロパティの文字列は消去され，ほかのテキストには置き換えられません。


Masking input characters
Masking input characters1079056

Section topics	参照

独自に作成するダイアログボックスでは，ユーザーが編集フィールドに入力した文字をマスクできます。編集ボックスコンポーネントの PasswordChar プロパティを使うと，ユーザーが入力した文字をアスタリスク［*］などの特殊文字で表示できます。

Delphi の［パスワード］ダイアログでは，編集ボックスコンポーネント (Password) の PasswordChar プロパティにはすでに * が指定されています。ユーザーが実行時にこのダイアログボックスにテキストを入力すると，アスタリスクだけが表示されます。ユーザーのパスワードは画面に表示されません。

実行時にパスワード入力フォームテンプレートを表示する場合は新しいプロジェクトで次のようにします。

1.	Form1 にボタンを追加し，次の OnClick イベントハンドラを作成します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  PasswordDlg.ShowModal;

end;

2.	Unit1 の uses 節にパスワードを追加し，アプリケーションを実行します。

3.	Button1 を選択して［パスワード入力］ダイアログボックスを表示します。

4.	編集ボックスに適当なテキストを入力します。
アスタリスクだけが表示されます。

入力文字をマスクして表示するパスワードダイアログボックス：


Specifying forms to auto-create
Specifying forms to auto-create1079057

Section topics	参照

プロジェクトのメインフォームとして指定したフォームは，アプリケーションを実行すると必ず「作成」されます。つまりメモリに読み込まれます。コードで特別な指定をしない限り，メインフォームが最初に読み込まれます。プロジェクトに追加したほかのフォームは実行時に自動的に作成されます。

これには，特にフォーム作成用のコードを記述しなくてもアプリケーションのすべてのフォームを表示できる利点があります。もちろん，フォームを表示したり隠す操作は必要です。ただし，アプリケーションを初めて実行する場合，アプリケーションの全てのフォームをメモリ内に作成しないこともできます。つまり，フォームをいつ作成するかをプログラムで制御したい場合です。たとえば，複数のさまざまなフォームを自動的にデータベースに接続するよりは，必要なときだけ各フォームを作成する方がいいはずです。

実行時に自動作成するフォームを明示的に指定するには［プロジェクトオプション］ダイアログボックスを使います。

実行時にフォームを自動作成するかどうかを指定する手順は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選択して，［フォーム］ページを選びます。
プロジェクトのすべてのフォームの名前が［自動作成の対象(A)］リストに表示されます。

2.	［自動作成の対象(A)］リストで，実行時にメモリ内に作成しないフォームを選択してから，［>］ボタンを選びます。リストのすべてのフォーム名を別のリストへ移動するには，［<<］ボタンまたは［>>］ボタンを選択します。
選択したファイルが［選択可能なフォーム(F)］リストに移動します。このリストに表示されたフォームは実行時に自動作成されません。

3.	［OK］を選択します。

メモ	一般には，アプリケーションのフォームは自動作成するのが一番です。フォームを自動作成しない場合は，フォームを実行時に作成するためのコードを特別に記述しなければなりません。フォームを作成する前に Show メソッドなどを呼び出してフォームを参照しようとすると例外が生成されます。

実行時のフォームの作成についての詳細は，オンラインヘルプの「フォームのインスタンス化」を参照してください。


Controlling the form auto-create order
Controlling the form auto-create order1079058

Section topics	参照

実行時にはまずメインフォームが作成され，次に［自動作成の対象(A)］リストにあるフォームがリスト上の順番で作成されます。リストのフォーム名の位置を変更すると，フォームの作成順を変更できます。たとえば，ほかのフォームと依存関係のあるフォームを設計した場合は，依存先のフォームが最初に作成されるような順番にします。

フォームの作成順を変更するには次のようにします。

［自動作成の対象(A)］リストでフォーム名を選択し，それを希望の位置へドラッグする

メモ	［プロジェクトオプション］ダイアログボックスの［フォーム］ページで指定したメインフォームと自動作成順は，プロジェクト (.DPR) ファイルの Application.CreateForm 文に反映されます。


MDI and SDI forms
MDI and SDI forms1079059

Section topics	参照

設計したフォームは MDI (マルチドキュメントインターフェース) フォームまたは SDI (シングルドキュメントインターフェース) フォームとしてアプリケーションに実装できます。MDI アプリケーションでは，1 つの親ウィンドウ内で複数のドキュメントや子ウィンドウを開けます。たとえば，表計算やワードプロセッサなどのアプリケーションの多くは MDI です。一方，SDI アプリケーションでは通常 1 つのドキュメントしか開けません。

一般的には，MDI フォームは最初から MDI フォームとして設計します。しかし，作成したフォームの FormStyle プロパティを変更して，MDI フォームや SDI フォームに変更することもできます。

次の表に FormStyle プロパティの各設定と作成フォームを示します。

FormStyle 値	作成されるフォーム	説明
fsNormal	スタンドアロンの SDI フォーム
fsMDIChild	MDI の子フォーム	このフォームは実行時に MDI 親フォームに入る
fsMDIForm	MDI の親フォームまたはフレームフォーム	このフォームは実行時にほかのフォームを入れることができる
fsStayOnTop	実行時にほかに開いているフォームの手前に表示されるスタンドアロンフォーム
MDI 親子フォームのサンプル

どちらのフォームもサイズ変更や移動ができます。ただし，子フォームは親フォームの境界の外に出ることはできません。

MDI アプリケーションについての詳細は「MDI アプリケーションの作成」を参照してください


See also1079060

デフォルトの新規フォームを指定する

デフォルトのメインフォームを指定する

フォーム，基本的な構築ブロック

フォームのキーボードショートカット

［位置合わせ］ダイアログボックス

コンポーネントパレットについて

Windows コモンダイアログボックスの使い方

ボタンおよび類似のコントロール

MDI アプリケーションの作成


Using data modules
Using data modules1057001

Section topics	参照

データモジュールは，アプリケーションの非ビジュアルコンポーネントを集めて処理するための Delphi の特別なクラスです。一般的には，これらはデータアクセスコンポーネント (TSession，TDatabase，TTable，TQuery，TStoredProc，および TBatchMove) ですが，他の非ビジュアルコンポーネント (たとえば TTimer，TOpenDialog，TSaveDialog，および TImageList) でもかまいません。データモジュールを使うと次のことができます。

設計時に，各アプリケーションフォームで複製するかわりに，データアクセスコンポーネントをすべて単一のビジュアルコンテナに置く

各フォームごとに別々に再作成するかわりに，多くのフォームで前に使用したテーブルや待ち行列を設計する

「コンポーネントイベント，データモジュールのユニットコードへの追加メソッドの使い方」のビジネス規則を作成する

保守を簡単にするために，ビジネス論理とデータアクセスをユーザーインターフェースから分離する

コモンダイアログ，タイマー，DDE クライアント，DDE クライアント項目，DDE サーバー，DDE サーバー項目，およびイメージリストをアプリケーション全体にわたって標準化する

適切に設計されたデータアクセスモジュールをオブジェクトリポジトリに保管してほかのプロジェクトや開発者と共有する


Using standard data modules and remote data modules
Using standard data modules and remote data modules1057002

Section topics	参照

データモジュールには，標準とリモートの 2 つのタイプがあります。1 層または 2 層のアプリケーションを作成する場合は，必ず標準データモジュールを使います。Delphi Client/Server Suite で，多層のデータベースアプリケーションを作成する場合は，リモートデータモジュールをアプリケーションサーバーに追加する必要があります。リモートデータモジュールをプロジェクトに追加する方法については，「リモートデータモジュールをアプリケーションサーバープロジェクトに追加する」を参照してください。


Creating a new data module
Creating a new data module1057003

Section topics	参照

新しい，空のデータモジュールをプロジェクトに作成するには，［ファイル(F)｜データモジュールの新規作成(M)］を選択します。デスクトップにデータモジュールコンテナが開かれ，プロジェクトファイルにデータモジュールが追加されます。

設計時のデータモジュールは背景が白くて調整グリッドのない標準的な Delphi のフォームに見えます。フォームでは，非ビジュアルコンポーネントをコンポーネントパレットからモジュール上に置き，追加したコンポーネントに合うようにデータモジュールをサイズ変更することができます。また，モジュールを右クリックして，コンテキストメニューを表示することもできます。以下の表は，データモジュールのコンテキストメニューオプションを要約したものです。

メニュー項目	目的
グリッドに合わせる(G)	表示されないモジュールのグリッドにデータアクセスコンポーネントを調整する
位置合わせ(A)	［位置合わせ］ダイアログボックスで指定した基準にしたがってデータアクセスコンポーネントを調整する
継承元の値に戻す(I)	オブジェクトリポジトリの別のモジュールから継承したモジュールに行った変更を破棄し，元の継承モジュールに戻る
作成順序(C)	起動時にデータアクセスコンポーネントが作成された順序を変更可能にする
リポジトリに追加(R)	オブジェクトリポジトリのデータモジュールへのリンクを保管する
テキストとして表示(V)	データモジュールのプロパティのテキスト表示
データモジュールコンテナの背後には，ソースコードを含みデータモジュールに対応するユニットファイルがあります。


Naming a data module and its unit file
Naming a data module and its unit file1057004

Section topics	参照

データモジュールのタイトルバーにはモジュール名が表示されます。データモジュールのデフォルト名は「DataModuleN」で，N はプロジェクトの最小の未使用ユニットを表す番号です。たとえば，新規プロジェクトを開始し，他のアプリケーションの構築前にそのプロジェクトにモジュールを追加する場合，モジュールのデフォルトの名前は「DataModule2」となります。DataModule2 に対応するユニットファイルのデフォルト名は「Unit2」です。

もっと説明的な名前にするには，設計時にデータモジュールとその対応するユニットファイルの名前を変更する必要があります。オブジェクトリポジトリやモジュールを使うアプリケーションの他のファイルとの名前の重複を避けるためにも，特にリポジトリに追加したデータモジュールは名前を変更する必要があります。

データモジュールの名前を変更する手順は次のとおりです。

1.	モジュールを選択します。

2.	オブジェクトインスペクタのモジュールの Name プロパティを編集します。

モジュールに付けた新しい名前は，オブジェクトインスペクタの Name プロパティからフォーカスがなくなると，タイトルバーに表示されます。

設計時にデータモジュールの名前を変更すると，コードのインターフェース部の変数の名前が変わります。また，手続き部で使用する名前も変わります。独自に作成したコードで参照するデータモジュール名は手作業で変更する必要があります。

データモジュールのユニットファイルの名前を変更する手順は次のとおりです。

1.	ユニットファイルを選択します。

2.	［ファイル(F)｜名前を付けて保存(A)］を選択します。

3.	［名前を付けて保存］ダイアログボックスで，名前を変更したデータモジュールを持つユニットを明確に指定するファイル名を入力します。


Placing and naming components
Placing and naming components1057005

Section topics	参照

フォームにビジュアルコンポーネントを置くのと同じように，データモジュールに TTable や TQuery のような非ビジュアルコンポーネントを置くことができます。コンポーネントパレットの該当するページで希望するコンポーネントをクリックし，次にデータモジュールをクリックして，コンポーネントに置きます。データモジュールには，グリッドのようなビジュアルなコントロールを置くことはできません。コントロールを置くとエラーメッセージが表示されます。

使いやすくするため，コンポーネントはデータモジュールに名前で表示できます。最初にコンポーネントを置いたとき，DataSource1 や Table1 のようにそのコンポーネントがどのようなものかを表す一般的な名前が割り当てられます。これにより，プロパティやメソッドで作業したい特定のコンポーネントの選択が容易になります。また，処理しやすいようにもっと説明的な名前 (たとえば，CustSource や CusTTable) をコンポーネントに付けることもできます。

データモジュールのコンポーネントの名前を変更する手順は次のとおりです。

1.	コンポーネントを選択します。

2.	オブジェクトインスペクタでコンポーネントの Name プロパティを編集します。

コンポーネントの新しい名前は，オブジェクトインスペクタの Name プロパティにフォーカスがなくなるとすぐに，データモジュールのアイコンの下に表示されます。

コンポーネントに名前を付けるとき，その名前は使用されるコンポーネントのタイプを反映していなければなりません。たとえばデータベースコンポーネントの場合，名前はコンポーネントのタイプ，アクセスするデータベースを反映していなければなりません。たとえば，アプリケーションで CUSTOMER テーブルを使用するものとします。CUSTOMER にアクセスするには，最小限 2 つのデータアクセスコンポーネント，すなわちデータソースコンポーネントとテーブルコンポーネントが必要です。これらのコンポーネントをデータモジュールに置くと，DataSource1 と Table1という名前が割り当てられます。これらのコンポーネントに CUSTOMER を反映させ，コンポーネントをお互いに関連付けるには，その名前を CustSource と CustTable に変更します。


Using component properties and methods in a data module
Using component properties and methods in a data module1057006

Section topics	参照

データモジュールにコンポーネントを置くとアプリケーション全体のためにその動作を集中管理できます。たとえば，TTable や TQuery のようなデータセットコンポーネントのプロパティを使うと，このデータセットを使うデータソースコンポーネントが使用できるデータを制御できます。データセットの ReadOnly プロパティに True を設定すると，フォームでデータベース対応のビジュアルコントロールで表示されるデータをユーザーが編集するのを妨ぐことができます。また，項目エディタをデータセットに呼び出して，データソースすなわちフォームのデータベースコントロールで使えるテーブルや待ち行列内のフィールドを制限することができます。

データモジュールでコンポーネントに設定したプロパティは，そのモジュールを使うユーザーのアプリケーションのすべてのフォームに一貫して適用されます。

プロパティのほかに，コンポーネントに対してもイベントハンドラを作成できます。たとえば，TDataSource コンポーネントには，OnDataChange，OnStateChange，OnUpdateData の 3 つのイベントを含むことができます。TTable コンポーネントには，設定できるイベントが 20 以上もあります。このようなイベントを使うと，アプリケーションを通してデータ操作を管理する，一貫性のある処理方法を提供できます。


Creating business rules in a data module
Creating business rules in a data module1057007

Section topics	参照

データモジュールのコンポーネントにイベントハンドラを作成するほかに，データモジュールのユニットファイルにメソッドを直接記述することができます。これらのメソッドは，データモジュールの一貫した処理方法として使うフォームに適用されます。たとえば，手続きを作成して月間や四半期，あるいは年末の帳簿を作成したい場合があります。あるいはデータモジュールのコンポーネントのイベントハンドラから手続きを呼び出したい場合もあります。

データモジュール用に作成した手続きと関数のプロトタイプは，モジュールの type 宣言部に記述する必要があります。

type

  TCustomerData = class(TDataModule)

    Customers: TTable;

    Orders: TTable;

    ...

  private

    { Private 宣言 }

  public

    { Public 宣言 }

    procedure LineItemsCalcFields(DataSet: TDataSet); { 追加の手続き }

  end;

var

  CustomerData: TCustomerData;

作成した手続きと関数は，モジュール用のコードの implementation 部の後に記述しなければなりません。


Adding a remote data module to an application server project
Adding a remote data module to an application server project1057008

Section topics	参照

Delphi Client/Server Suite で，多層データベースアプリケーションを構築している場合，リモートデータモジュールをアプリケーションサーバープロジェクトに追加することができます。リモートデータモジュールは，AsctiveX 化が可能なデータモジュールで，アプリケーションサーバーを OLE 自動オブジェクトにして，クライアントマシンからリモートアクセスできるようにします。多層データベースアプリケーション，アプリケーションサーバー，リモートデータモジュールの作成方法についての情報，およびリモートデータモジュールの使い方についての詳細は『開発者ガイド』を参照してください。

リモートデータモジュールをプロジェクトに追加する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択します。

2.	［新規作成］ダイアログボックスで［新規作成］ページを選択します。

3.	［リモートデータモジュール］を選択します。

プロジェクトにリモートデータモジュールをおくと，これを標準データモジュールのように使用することができます。OLE 自動作成および登録は自動的に行われます。


Reusing data modules in the Object Repository
Reusing data modules in the Object Repository1057009

Section topics	参照

初めからデータモジュールを作成する代わりに，オブジェクトリポジトリにある既存のデータモジュールを利用できます。「オブジェクトの共有」を参照してください。そこでは，使用可能な項目のコピー，継承，直接使用を含むプロセスについて説明しています。また，データモジュールのコピー，継承，直接使用については以下の節を参照してください。


Copying a data module
Copying a data module1057010

Section topics	参照

データモジュールは，次の場合にオブジェクトリポジトリからコピーします。

モジュールがすでにアプリケーションが必要とするデータへのアクセスの基礎レベルに達しているとき

モジュール内のコンポーネントのかなりの変更と追加をアプリケーションが必要としているとき

リポジトリの上位データモジュールに，アプリケーションのモジュールに影響するような変更を加えたくないとき

メモ	将来，リポジトリの上位データモジュールを変更する可能性があり，その変更がプロジェクトに反映されるようにしたい場合，データモジュールはコピーするのではなく継承する必要があります。


Inheriting a data module
Inheriting a data module1057011

Section topics	参照

データモジュールは，次の場合にオブジェクトリポジトリから継承します。

モジュールがアプリケーションの必要とするデータへのアクセスの基礎レベルに達しているとき

リポジトリの上位データモジュールに行われた変更をアプリケーションのモジュールに反映したいとき (たとえば，すべてのアプリケーションのデータの一貫した共通の表示形態を維持するため)

継承したデータモジュールのコピーにコンポーネントとイベントハンドラを追加した場合，追加するコンポーネントとイベントハンドラ用の新しいコードはアプリケーションにだけ作成します。

メモ	TSession や TDatabase コンポーネントを含むデータモジュールを継承してはいけません。これらのモジュールは継承するのではなくコピーする必要があります。2 番目のオプションでは，使用できる別々のデータモジュールに TSession と TDatabase コンポーネントを置き，継承できる別のデータモジュールに他のすべてのコンポーネントを置きます。

Inheriting event handlers1057012

データモジュールから継承したコンポーネントのイベントハンドラをオーバーライドした場合 (たとえば，アプリケーションに固有の機能を提供するために)，継承したハンドラを新しいハンドラから呼び出すことができます。ハンドラをオーバーライドすると，新しいハンドラが単独の文である inherited 文により作成されます。この呼び出しは，上位データモジュールにイベントハンドラがある場合にそれを呼び出します。イベントハンドラがない場合は，inherited 文は無視されます。新しいハンドラから継承ハンドラを呼び出したくない場合は，inherited 文を削除します。


"Using" a data module
"Using" a data module1057013

Section topics	参照

データモジュールは，オブジェクトリポジトリからアプリケーションにコピーすることも，［新規作成］ダイアログボックスで［直接使用(U)］を選択してリポジトリ内の元のモジュールを置き換えるような変更を行うこともできます。

リポジトリのデータモジュールは次の場合に使用します。

モジュールがすでにアプリケーションが必要とするデータへのアクセスの基礎レベルに達しているとき

モジュール内のコンポーネントのかなりの変更と追加をアプリケーションが必要としているとき

アプリケーションに必要な変更が他のアプリケーションにも基本的に適用できるとき

重要	［直接使用(U)］オプションは注意が必要です。データモジュールに行う変更は，他のユーザーがリポジトリから各自のアプリケーションにこれをコピーする前に徹底的にテストするようにしてください。


Accessing a data module from a form
Accessing a data module from a form1057014

Section topics	参照

フォームのビジュアルコントロールをデータモジュールに関連付けるには，まずデータモジュールをフォームの uses 節に追加する必要があります。フォームの uses 節にモジュールを追加するには，次のようにします。

［ファイル(F)｜ユニットを使う(U)］を選択して，モジュールの名前を入力するか，または［ユニットの使用］ダイアログボックスのリストボックスから選択します。

データモジュールの TTable または TQuery コンポーネントのフィールドエディタから，選択したフィールドをフォームにドラッグします。この場合，モジュールをフォームの uses 節に追加したいかどうか確認するプロンプトがあり，その後フォームにドラッグした各フィールドに関するデータディクショナリ情報に基づきコントロールが作成されます。

フィールドをフォームにドラッグする前に，ドラッグしようとしているフィールドのデータソースを設定します。すでにデータセットに接続されている場合，Delphi ではデータモジュール内の既存のデータソースを使用します。

データソースが定義されていない場合は，新しいデータソースコンポーネントがフォームに追加され，このデータソースを指定するコントロールの DataSource プロパティが設定されます。データソース自体はデータモジュールのテーブルまたは待ち行列コンポーネントに関係付けられます。この場合，この調整を保持することもできます。またはデータアクセスモデルをきれいに維持するために変更もできます。それには，フォームのデータソースコンポーネントを削除し，フォームのコントロールの DataSource プロパティを設定して，データモジュールの適切なデータソースを直接指定します。


See also1057015

ユニットファイル

多層アプリケーションの作成

ActiveX の Web アプリケーション化

コピー，継承，直接使用オプション


Using the Menu Designer
Using the Menu Designer1068001

Section topics	参照

メニューを使用すると，ユーザーは論理的にまとめられたコマンド群を簡単に実行できます。Delphi のメニューデザイナでは，設計済みのメニューもカスタムメニューも，簡単にフォームへ追加できます。メニューを追加する手順は，フォームにメニューコンポーネントを追加し，メニューデザイナを開き，メニューデザイナウィンドウにメニュー項目を直接入力するだけです。設計時には，メニュー項目の追加，削除，ドラッグアンドドロップなどを行って，配置を整えることができます。

設計の結果は，プログラムを実行しなくても確認できます。メニュー設計は，設計時においても実行時と同じようにフォームに表示されるからです。なお，実行時にコードでメニューを変更し，追加情報やオプションをユーザーに提供することもできます。

この章では，メニューデザイナを使用してメニューバーやポップアップ (ローカル) メニューを設計する方法を説明します。この節で説明する設計時と実行時のメニューに関する操作は以下のとおりです。

メニューデザイナを開く

メニューの構築

オブジェクトインスペクタのメニュー項目の編集

メニューデザイナのスピードメニューの使い方

メニューテンプレートの使い方

メニューをテンプレートとして保存する

メモ	実行時にメニュー操作を行うコードの例は，サンプルアプリケーションについて解説している「MDI アプリケーションの作成」を参照してください。


Opening the Menu Designer
Opening the Menu Designer1068002

Section topics	参照

メニューデザイナの使用を始める前に，MainMenu コンポーネントまたは PopupMenu コンポーネントをフォームに追加します。どちらのメニューコンポーネントもコンポーネントパレットの［Standard］ページにあります。

MainMenu コンポーネントでは，フォームのタイトルバーに結び付けるメインメニューを作成します。PopupMenu コンポーネントでは，ユーザーがフォームで右クリックしたときに表示するポップアップメニューを作成します。なお，ポップアップメニューにメニューバーはありません。

メニューデザイナを開くには，フォームでメニューコンポーネントを選択し，以下のいずれかを行います。

メニューコンポーネントをダブルクリックする

オブジェクトインスペクタの［プロパティ］ページで Items プロパティを選択し，値列をダブルクリックするか，［...］(省略記号) ボタンをクリックする

メニューデザイナが表示されます。メニューデザイナでは最初の空白のメニュー項目が強調表示になり，入力を始めるとオブジェクトインスペクタの Caption プロパティに入ります。

メインメニューのためのメニューデザイナ

ポップアップメニューのためのメニューデザイナ


Building menus
Building menus1068003

Section topics	参照

アプリケーションに含めるすべてのメニューのために，フォームに対してメニューコンポーネントを追加します。各メニューを作成するには，最初から独自に構築するか，または Delphi の設計済みメニューテンプレートを使用します。

この節では，設計時にメニューを作成するための基本を説明します。Delphi のメニューテンプレートについての詳細は「メニューテンプレートの使い方」を参照してください。


Naming menus
Naming menus1068004

Section topics	参照

すべてのコンポーネントに共通することですが，フォームにメニューコンポーネントを追加するとデフォルトの名前 (たとえば MainMenu1) が付けられます。このデフォルト名を変更し，Object Pascal の命名規則に従って別の具体的な名前を付けることもできます。なお，Object Pascal 言語についての詳細は「Object Pascal コードの書き方」参照してください。

Delphi ではフォームの型宣言にメニュー名を追加します。このメニュー名はオブジェクトインスペクタのコンポーネントリストに表示されます。


Naming the menu items
Naming the menu items1068005

Section topics	参照

メニューコンポーネント自体とは異なり，メニュー項目には明示的に名前を付けてフォームに追加します。メニュー項目に名前を付けるには以下の 2 通りの方法があります。

Name プロパティに値を直接入力する

最初に Caption プロパティに値を入力し，これによって間接的に Name プロパティの値を設定する
たとえば，メニュー項目に Caption プロパティ値として File を指定すると，このメニュー項目の Name プロパティに File1 が指定されます。Caption プロパティに値を入力する前に Name プロパティに値を入力しても，Caption プロパティは値が入力されるまで空白になります。

メモ	Object Pascal 識別子として無効な文字を Caption プロパティに入力した場合は，Delphi が Name プロパティを適切に変更します。たとえば，Caption の先頭に数字を使用した場合，Delphi は数字の前に文字を付けて Name プロパティ値を作成します。

次の表に例を示します。表中のすべてのメニュー項目は同一のメニューバーに表示されているものとします。

コンポーネントの Caption プロパティ値	作成される Name プロパティ値	説明
&File	File1	アンド記号 (&) を除去する
&File (2 つ目)	File2	重複項目を数字で区別する
1234	N12341	先頭に文字，末尾に数字を追加する
1234 (2 つ目)	N12342	同上 (重複項目を区別)
$@@@#	N1	命名規則に合わない文字をすべて除去し，先頭に文字，末尾に数字を追加する
- (ハイフン)	N2	同様に，命名規則に合わない文字を除去し，先頭に文字，末尾に重複しないように数字を追加する
メニューコンポーネントと同じように，フォームの型宣言にメニュー項目名が追加されます。このメニュー項目名はオブジェクトインスペクタのコンポーネントリストに表示されます。


Adding, inserting, and deleting menu items
Adding, inserting, and deleting menu items1068006

Section topics	参照

次の手順は，メニュー構造を構築するための基本的な作業を示しています。なお，各ステップでは，メニューデザイナウィンドウを開いていることを前提にしています。

設計時にメニュー項目を追加する手順は次のとおりです。

1.	メニュー項目を作成する位置を選択します。
初めて開いたメニューデザイナでは，メニューバーの最初の位置がすでに選択されています。

2.	Caption プロパティの値を入力します。または，オブジェクトインスペクタの Name プロパティにカーソルを移してから値を入力します。この場合は，Caption プロパティを再び選択して値を入力します。

3.	〔Enter〕を押します。
メニュー項目を配置するための次のプレースホルダが選択されます。
手順の 2 で最初に Caption プロパティを入力した場合は，矢印キーでそのメニュー項目に戻って，Caption に入力した値に従って Name プロパティが設定されているのを確認します。詳細は「メニュー項目の名前」を参照してください。

4.	新しく作成する各項目の Name プロパティと Caption プロパティに引き続き値を入力するか，〔Esc〕を押してメニューバーに戻ります。
矢印キーでメニューバーからメニューへ移動し，さらにリスト内の項目間を移動します。操作を完了するには〔Enter〕を，メニューバーに戻るには〔Esc〕を押します。

新しい空白のメニュー項目を挿入する手順は次のとおりです。

1.	メニュー項目にカーソルを配置します。

2.	〔Ins〕を押します。

メニュー項目はメニューバーで選択されている項目の左に挿入されます。メニューリストでは選択されている項目の上に挿入されます。

メニュー項目，つまりメニューコマンドを削除する手順は次のとおりです。

1.	削除するメニュー項目にカーソルを配置します。

2.	〔Del〕を押します。

メモ	デフォルトのプレースホルダは削除できません。デフォルトのプレースホルダはメニューリストに最後に入力した項目の下か，またはメニューバーの最後の項目の横に表示されます。このプレースホルダは実行時のメニューには表示されません。

Adding separator bars1068007

分割線はメニュー項目間に引かれる線です。分割線を使って，メニューリスト内のグループ分けを示したり，リストを単に見やすいように分けたりできます。

メニュー項目を分割線として設定するには次のようにします。

Caption にハイフン (-) を入力する

Specifying accelerator keys and keyboard shortcuts1068008

アクセラレータキーを使用すると，ユーザーはキーボードで〔Alt〕キーと適切な文字キーを同時に押すことによってメニューコマンドにアクセスできます。適切な文字とは， コードでアンド記号 (&) の次にある文字です。アンド記号に続く文字はメニューに下線付きで表示されます。

キーボードショートカットを使用すると，ユーザーはメニューにアクセスせずに，ショートカットキーの組み合わせを入力して直接操作することができます。

アクセラレータを指定するには次のようにします。

その文字の前にアンド記号 (&) を付ける

たとえば，メニューコマンド Save にアクセラレータキーとして S を付けるには &Save と入力します。

キーボードショートカットを指定するには次のようにします。

オブジェクトインスペクタを使用して ShortCut プロパティに値を入力するか，またはドロップダウンリストでキーの組み合わせを選択する

ただしこのリストは，入力できる有効な組み合わせのほんの一部です。

追加したショートカットは，メニュー項目のキャプションの横に表示されます。

注意	Delphi は， ショートカットキーやアクセラレータの重複をチェックしません。アプリケーションのメニューに入力した値が重複していないか調べるようにしてください。


Creating submenus
Creating submenus1068009

Section topics	参照

アプリケーションメニューには，さらにドロップダウンリストを開き，関連した複数のコマンドを提供するものがあります。このような階層構造をネストといい，下のレベルのコマンド群をネストしたメニューまたはサブメニューと呼びます。ネストしたメニューを持つメニュー項目では，その右に右向きの三角形が示されます。Delphi では，いくらでも必要なだけネストしたメニューを構築できます。

メニューをネスト構造にすると，縦に長すぎるメニューを短くすることができます。ただし，インターフェースの使いやすさを考えて，ネストの階層は 2～3 レベル (ポップアップメニューの場合は 1 レベル) ほどに抑えるべきです。

サブメニューを作成する手順は次のとおりです。

1.	サブメニューを作成するメニュー項目を選択します。

2.	〔Ctrl〕+〔→〕を押して最初のプレースホルダを作成するか， スピードメニューの［サブメニューの作成(C)］を選択します。

3.	このプレースホルダ内にサブメニュー項目の名前を入力するか，既存のメニュー項目をドラッグします。

4.	〔Enter〕または〔↓〕を押して，次のプレースホルダを作成します。

5.	サブメニュー内に作成する項目ごとに手順の 3 と 4 を繰り返します。

6.	〔Esc〕を押して前のメニューレベルに戻ります。

Creating submenus by demoting existing menus1068010

メニューバーやメニューテンプレートのメニュー項目を，リストのメニュー項目間に挿入して，サブメニューを作成することもできます。メニューを既存のメニュー構造内に移動すると，このメニューに関連付けられたすべての項目も含めた全体をサブメニューにすることができます。サブメニューに対しても同じことができます。つまり，メニュー項目を既存のサブメニュー内に移動すると，もう 1 つ下位レベルのサブメニューを作成できます。

Moving menu items1068011

設計時にはドラッグアンドドロップだけでメニュー項目を移動できます。たとえば，メニューバー上を移動したり，メニューリストのほかの場所に移動したり，ほかのメニュー内に移動できます。

ただし，直系のネスト階層間での移動はできません。つまり，メニューバーのメニュー項目をそのメニュー自身の中へ移動したり，あるいは，あるメニュー項目をそのメニュー項目自身の下にあるサブメニュー内へ移動することはできません。一方，ほかの系列のメニューに移動するのであれば，メニュー項目の移動先と移動元のレベルに制限はありません。

メニュー項目をドラッグするとカーソルの形が変わり，その位置にメニュー項目を挿入できるかどうかが示されます。メニューを移動すると，そのメニューに属するすべての項目も移動します。

メニューバー上にメニュー項目を移動する手順は次のとおりです。

1.	メニューバー上でメニュー項目をドラッグし，ドラッグカーソルの矢印で新しい位置を指します。

2.	マウスボタンを放してメニュー項目を新しい位置にドロップします。

メニュー項目をメニューリスト内に移動する手順は次のとおりです。

1.	メニューバー上で移動元のメニュー項目をドラッグし，ドラッグカーソルの矢印で移動先のメニュー項目を指します。
移動先のメニューが開き，移動元のメニュー項目を新しい位置にドラッグできる状態になります。

2.	リスト内に移動元のメニュー項目をドラッグし，マウスボタンを放して新しい位置にドロップします。


Viewing the menu
Viewing the menu1068012

Section topics	参照

メニューは設計時のフォームに表示できます。あらかじめプログラムコードを実行する必要もありません。なお，設計時のフォームにはポップアップメニューコンポーネントは表示されますが， ポップアップメニュー自体は表示されません。設計時にポップアップメニューを表示するには，メニューデザイナを使用します。

メニューを表示する手順は次のとおりです。

1.	メニューを表示するフォームが表示されていればメニューを表示するフォームをクリックします。フォームが表示されていなければ，［表示(V)］メニューでフォームを選択します。

2.	フォームに複数のメニューがあれば，表示したいメニューをフォームの Menu プロパティのドロップダウンリストで選択します。
プログラムの実行時に表示されるとおりのメニューがフォームに表示されます。


Editing menu items in the Object Inspector
Editing menu items in the Object Inspector1068013

Section topics	参照

ここまでは，メニューデザイナでメニュー項目に Name や Caption などのプロパティを設定する方法を説明しました。

また，フォームで選択したコンポーネントの場合と同じように，ShortCut プロパティなどのメニュー項目のプロパティをオブジェクトインスペクタで直接設定する方法も説明しました。

メニューデザイナでメニュー項目を編集しているとき，オブジェクトインスペクタにはそのメニュー項目のプロパティが表示されています。そのため，オブジェクトインスペクタにフォーカスを切り替えるだけで，そのメニュー項目のプロパティを編集できます。一方，メニューデザイナを使用せずに，オブジェクトインスペクタのオブジェクトセレクタでメニュー項目を選択してプロパティを編集することもできます。

メニューデザイナウィンドウを閉じてメニュー項目の編集を続ける手順は，次のとおりです。

1.	オブジェクトインスペクタの［プロパティ］ページをクリックし，メニューデザイナウィンドウからオブジェクトインスペクタへフォーカスを切り替えます。

2.	メニューデザイナの［システムメニュー｜閉じる(C)］を選択するか，クローズボタンをクリックします。
フォーカスはオブジェクトインスペクタ内に残ります。したがって，選択したメニュー項目のプロパティを引き続き編集できます。別のメニュー項目を編集するには，オブジェクトセレクタで項目を選択します。


Using the Menu Designer context menu
Using the Menu Designer context menu1068014

Section topics	参照

メニューデザイナのスピードメニューを使うと，一般的なメニューデザイナコマンドやメニューテンプレートオプションを簡単に利用できます。なお，メニューテンプレートについての詳細は「メニューテンプレートの使い方」を参照してください。

スピードメニューを表示するには次のようにします。

メニューデザイナウィンドウを右クリックするか，メニューデザイナウィンドウ内にフォーカスがあるときに〔Alt〕+〔F10〕を押す


Commands on the context menu
Commands on the context menu1068015

Section topics	参照

次の表にメニューデザイナのスピードメニューコマンドをまとめます。

メニューコマンド	動作
追加(I)	カーソルの上または左にプレースホルダを挿入する
削除(D)	選択したメニュー項目を削除する サブ項目がある場合は，それも一括して削除する
サブメニューの作成(C)	ネストレベルのプレースホルダを作成し，選択したメニュー項目の右に右向き三角を表示する
メニューの選択(L)	現在のフォームでメニューのリストを開く メニュー名をダブルクリックするとメニューのデザイナウィンドウが開く
テンプレートとして保存(S)	［テンプレートを保存］ダイアログボックスを開く 将来の再利用のためにメニューを保存できる
テンプレートを挿入(N)	［テンプレートを挿入］ダイアログボックスを開く 再利用するテンプレートを選択できる
テンプレートを削除(E)	［テンプレートを削除］ダイアログボックスを開く 既存のテンプレートを削除できる
リソースから追加(R)	［リソースから追加］ダイアログボックスを開く 現在のフォームで開く .MNU ファイルを選択できる


Switching among menus at design time
Switching among menus at design time1068016

Section topics	参照

1 つのフォーム上で複数のメニューを設計している場合，メニューデザイナのスピードメニューやオブジェクトインスペクタを使って，メニュー間を簡単に移動，選択できます。

スピードメニューでフォームのメニュー間を切り替える手順は次のとおりです。

1.	メニューデザイナ内で右クリックしてスピードメニューを表示します。

2.	スピードメニューで［メニューの選択(L)］を選択します。
［メニューの選択］ダイアログボックスが表示されます。

このダイアログボックスには，メニューデザイナで現在開いているメニューが属するフォームに関連付けられた，すべてのメニューが一覧表示されます。

3.	［メニューの選択］ダイアログボックスのリストで，表示または編集するメニューを選択します。

オブジェクトインスペクタを使ってフォームのメニュー間を切り替える手順は次のとおりです。

1.	選択するメニューを含むフォームにフォーカスを与えます。

2.	オブジェクトセレクタで，編集するメニューを選択します。

3.	オブジェクトインスペクタの［プロパティ］ページでこのメニューの Items プロパティを選択し，［...］ボタンをクリックするか，値列をダブルクリックします。


Using menu templates
Using menu templates1068017

Section topics	参照

Delphi では，頻繁に使用するコマンドを入れた設計済みのメニュー，つまりメニューテンプレートがいくつか提供されています。これらのメニューテンプレートは，そのまま変更せずにアプリケーションで使用できます。また，これを基にしてカスタマイズし，最初から独自に設計したメニューと同じように扱うこともできます。なお，メニューテンプレートにはイベントハンドラコードは含まれていません。

Delphi に添付されたメニューテンプレートは，デフォルトインストールの状態で \Program Files\Borland\Delphi 3\Bin ディレクトリに格納されます。このファイルには拡張子 .DMT (Delphi メニューテンプレートを意味する) が付いています。

独自に設計したメニューを，メニューデザイナでテンプレートとして保存することもできます。テンプレートとして保存したメニューは，設計済みのメニューと同じように使用できます。また，必要でないメニューテンプレートはリストから削除することもできます。

アプリケーションにメニューテンプレートを追加する手順は次のとおりです。

1.	メニューデザイナウィンドウを右クリックします。
メニューデザイナのスピードメニューが表示されます。

2.	［テンプレートを挿入(N)］を選択します。
なお，テンプレートが存在しない場合，スピードメニューの［テンプレートを挿入(N)］コマンドは淡色表示になります。
［テンプレートを挿入］ダイアログボックスが開き，使用可能なメニューテンプレートのリストを表示します。

3.	挿入するメニューテンプレートを選択し，〔Enter〕を押すか［OK］を選択します。
メニューはフォームのカーソル位置に追加されます。たとえば，カーソルがリストのメニュー項目上にあると，メニューテンプレートはこの項目の上に挿入されます。カーソルがメニューバー上にあると，メニューテンプレートはカーソルの左に挿入されます。

メニューテンプレートを削除する手順は次のとおりです。

1.	メニューデザイナウィンドウを右クリックします。
メニューデザイナのスピードメニューが表示されます。

2.	［テンプレートを削除(E)］を選択します。
なお，テンプレートが存在しない場合，スピードメニューの［テンプレートを削除(E)］コマンドは淡色表示になります。
［テンプレートの削除］ダイアログボックスが開き，使用可能なテンプレートのリストが表示されます。

3.	削除するメニューテンプレートを選択し，［OK］を選択します。
テンプレートリストとハードディスクからテンプレートが削除されます。


Saving a menu as a template
Saving a menu as a template1068018

Section topics	参照

独自に設計したメニューも，テンプレートとして保存すれば後で再利用できます。メニューテンプレートを使うと，アプリケーションに一貫した外観を確保できるだけでなく，これを基にしてカスタマイズを進めることもできます。

保存したメニューテンプレートは，BIN サブディレクトリに .DMT ファイルとして格納されます。

メニューをテンプレートとして保存する手順は次のとおりです。

1.	再利用できるメニューを設計します。
このメニューにはいくつでも項目，コマンド，サブメニューを入れることができます。アクティブなメニューデザイナウィンドウ内のすべてが，1 つの再利用可能なメニューとして保存されます。

2.	メニューデザイナウィンドウ内を右クリックしてスピードメニューを開きます。

3.	［テンプレートとして保存(S)］コマンドを選択します。
［テンプレートとして保存］ダイアログボックスが表示されます。

4.	［テンプレートのコメント(T)］編集ボックスに，このメニューの簡単な説明文を入力して［OK］を選択します。
［テンプレートとして保存］ダイアログボックスが閉じるとメニュー設計が保存され，メニューデザイナウィンドウに戻ります。

メモ	入力した説明文は［テンプレートとして保存］，［テンプレートを挿入］，［テンプレートを削除］の各ダイアログボックスに表示されます。この説明文は，メニューの Name プロパティや Caption プロパティには影響しません。


Naming conventions for template menu items and event handlers
Naming conventions for template menu items and event handlers1068019

Section topics	参照

メニューをテンプレートとして保存するとき，このメニューの Name プロパティは保存されません。オーナーとなるフォーム内で，各メニューはユニークな名前を持たなければならないからです。そして，メニューデザイナで新しいフォームにテンプレートのメニューを挿入すると，このメニューとそのすべての項目には新しい名前が生成されます。

たとえば，ある File メニュー (メニューバーに File と表示される) をテンプレートとして保存するとします。元のメニュー名は MyFile とします。このメニューをテンプレートとして新しいメニューに挿入すると，このメニューの名前は File1 になります。ただし，挿入先にすでに File1 という同名のメニュー項目がある場合は，挿入するメニューの名前は File2 になります。

テンプレートでは，保存するメニューに関連付けられたイベントハンドラは保存されません。イベントハンドラコードが新しいフォームにも適用できるかどうかわからないからです。メニューテンプレート項目に新しいイベントハンドラを作成すると，そのイベントハンドラの名前が生成されます。

メニューテンプレート内の項目とフォームの既存の OnClick イベントハンドラとは，簡単に関連付けることができます。詳細については「メニュー項目と既存のイベントハンドラを関連付ける」を参照してください。


Manipulating menu items at runtime
Manipulating menu items at runtime1068020

Section topics	参照

追加の情報やオプションをユーザーに提供するために，アプリケーションの実行中にメニュー項目を既存のメニュー構造に追加する場合もあります。このようにメニュー項目を実行時に追加するには， Add メソッドまたは Insert メソッドを使用します。また，Visible プロパティを変更することで，メニュー項目の表示/非表示を切り替える方法もあります。Visible プロパティは，メニューにメニュー項目を表示するかどうかを指定します。メニュー項目を (非表示ではなく) 淡色表示にするには， Enabled プロパティを使用します。

メニュー項目の Visible プロパティと Enabled プロパティを使ったコードの例については「メニュー項目を使用不可にする」を参照してください。

MDI (マルチドキュメントインターフェース) と OLE (オブジェクトのリンクと埋め込み) の各アプリケーションでは，メニュー項目を既存のメニューバーにマージすることもできます。


Merging menus
Merging menus1068021

Section topics	参照

テキストエディタのサンプルのような MDI アプリケーションや，または OLE のクライアントアプリケーションでは，アプリケーションのメインメニューは別のフォームや OLE サーバーオブジェクトのメニュー項目を受け取れなければなりません。ほかのメニュー項目を取り込むことを，メニューのマージと呼びます。

メニューの 2 つのプロパティに値を指定して，マージの準備をします。

フォームの Menu プロパティ

メニュー内のメニュー項目の GroupIndex プロパティ


Specifying the active menu: Menu property
Specifying the active menu: Menu property1068022

Section topics	参照

Menu プロパティで，フォームのアクティブメニューを指定します。メニューのマージ操作はアクティブメニューだけに適用されます。フォームに複数のメニューコンポーネントがある場合は，コードで Menu プロパティを設定して実行時にアクティブメニューを変更できます。次に例を示します。

Form1.Menu := SecondMenu;


Determining the order of merged menu items: GroupIndex property
Determining the order of merged menu items: GroupIndex property1068023

Section topics	参照

GroupIndex プロパティで，マージするメニュー項目を共有メニューバーに表示する順番を指定します。メニュー項目のマージでは，メインメニューバーのメニュー項目を置き換えることも追加することもできます。

GroupIndex のデフォルト値は 0 です。GroupIndex の値は以下に示す意味を持ちます。

小さい数字のメニュー項目ほどメニューの最初 (左端) に表示される
たとえばファイルメニューなど，常に左端に表示するメニューの GroupIndex プロパティには 0 (ゼロ) を設定します。同じように，ヘルプメニューなど常に右端に表示するメニューには大きな数字を指定します。なお，GroupIndex の値は連続した数でなくてもかまいません。

メインメニューの項目を置き換えるには，子メニューの項目にメインメニューと同じ GroupIndex 値を指定する
これはグループ化された項目や単一の項目に対して使えます。たとえば，メインフォームに GroupIndex の値が 1 に設定されている Edit メニュー項目がある場合，このメニュー項目を置き換えるには子フォームの 1 つ以上のメニュー項目に，GroupIndex の値として 1 を指定します。
子フォームの複数のメニュー項目に同じ GroupIndex 値を指定しメインメニューにマージした場合は，各メニュー項目は元の順番を保持します。

メインメニューに項目を置き換えずに追加するには，メインメニューの項目の数値の範囲を広げて，子フォームの数値を間に「はめ込む」ようにする
たとえば，メインメニューの項目には 0 と 5 の数値を指定し，子フォームのメニュー項目には 1，2，3，4 の数値を指定して挿入します。


Importing resource (.RC) files
Importing resource (.RC) files1068024

Section topics	参照

Delphi では，ほかのアプリケーションで構築されたメニューも利用できます。ただし，標準の Windows リソース (.RC) ファイル形式のものに限ります。この種のメニューは Delphi プロジェクトに直接インポートできるので，同じメニューを再構築する時間と手間を省くことができます。

既存の .RC ファイル形式のメニューを読み込む手順は次のとおりです。

1.	メニューデザイナで，メニューを表示したい位置にカーソルを配置します。
インポートしたメニューは，そのまま変更せずに使用することも，設計中のメニューの一部として組み込むこともできます。

2.	スピードメニューから［リソースから追加(R)］を選択します。
［リソースから追加］ダイアログボックスが表示されます。

3.	このダイアログボックスで，読み込むリソースファイルを指定して［OK］を選択します。
メニューデザイナウィンドウにメニューが表示されます。

メモ	リソースファイルに複数のメニューがある場合は，最初に各メニューを個別のリソースファイルとして保存してからインポートします。


See also1068025

メニューイベントとコードの関連付け

リソースファイル

MDI アプリケーションの作成

メニューテンプレートの使い方


Working with event handlers
Working with event handlers1061001

Section topics	参照

Delphi では，記述するコードのほとんどはイベントに応じて直接または間接に実行されるものです。このようなコードをイベントハンドラといいます。実際には，イベントハンドラは一種の手続きです。この章では以下の内容について説明します。

デフォルトイベントハンドラの生成

新規イベントハンドラの生成

イベントハンドラの検索

イベントと既存のイベントハンドラの関連付け

メニューイベントとコードの関連付け


Generating the default event handler
Generating the default event handler1061002

Section topics	参照

デフォルトイベントとは，実行時にコンポーネントで処理される頻度の最も高いイベントです。たとえば，ボタンのデフォルトイベントは OnClick イベントになります。

デフォルトイベントハンドラを生成するには，フォームに配置したコンポーネントをダブルクリックします。コードエディタが開き，イベントハンドラを変更する必要のある場所にカーソルが配置されます。

メモ	Bevel などのコンポーネントは，ユーザーイベントを処理する必要がありません。したがって，このようなコンポーネントをフォームでダブルクリックしても，イベントハンドラは生成されません。また，Image コンポーネントやいずれかのメニューコンポーネントなどのように，ダブルクリックすると設計時にプロパティを編集するためのダイアログボックスが開くものもあります。

デフォルトイベントハンドラを作成するもう一つの方法は，オブジェクトインスペクタを使用する方法です。［イベント］ページで，イベントの値列をダブルクリックします。


Generating a new event handler
Generating a new event handler1061003

Section topics	参照

オブジェクトインスペクタを使って，フォームまたは，フォーム上のコンポーネント用のイベントハンドラを生成できます。オブジェクトインスペクタを使うと，コードの部分が生成され，保持されます。イベントハンドラの最初の行は，手続きを命名し，手続きが使うパラメータを指定します。begin..end ブロックの間に記述したコードは，イベントが起こると必ず実行されます。

オブジェクトインスペクタを使って，イベントハンドラを作成する方法は次のとおりです。

1.	コンポーネント (またはフォーム) を選択します。

2.	オブジェクトインスペクタの［イベント］タブをクリックします。
オブジェクトインスペクタの［イベント］ページでは，コンポーネントに関連付けることのできるすべてのイベントが表示され，デフォルトイベントが強調表示されています。

3.	必要なイベントを選択し，値列をダブルクリックするか，または〔Cntrl〕+〔Enter〕を押します。
Delphi はコードエディタにイベントハンドラを生成し，begin..endブロックの中にカーソルを配置します。

4.	begin..end ブロックの中に，イベントが起きたときに実行したいコードを入力します。

Delphi では，通常はオブジェクトインスペクタを使ってイベントハンドラを生成します。もちろん，オブジェクトインスペクタを使わずにコードエディタでソースコードを記述することもできます。たとえば，コンポーネントイベントと直接関連付けられていなくても，イベントハンドラから呼び出せる汎用のルーチンを記述できます。イベントハンドラーは手作業でも記述できますが，可能な限りオブジェクトインスペクタを使ってください。オブジェクトインスペクタを使うと，イベントハンドラ名が生成されるだけでなく，後にイベントハンドラ名をオブジェクトインスペクタを使って変更した場合にソースコード中のすべての同じ名前が変更されます。オブジェクトインスペクタを使わずに記述したイベントハンドラでは，このような処理はできません。


Locating event handlers
Locating event handlers1061004

Section topics	参照

フォームでコンポーネントをダブルクリックして，デフォルトイベントハンドラを生成した場合，同じ方法で (コンポーネントをダブルクリックして) 検索することができます。

コードエディタが開き，コンポーネントのデフォルトイベントハンドラのコードの 1 行目の先頭にカーソルが配置されます。


Locating an event handler that's not the default
Locating an event handler that's not the default1061005

Section topics	参照

デフォルト以外のイベントハンドラを検索する手順は次のとおりです。

1.	フォーム上の，検索するイベントハンドラに対応するコンポーネントを選択します。

2.	オブジェクトインスペクタで［イベント］タブを表示します。

3.	イベント列で，表示するコードに対応するイベントをダブルクリックします。
コードエディタが開き，イベントハンドラの begin..end ブロック内にカーソルが配置されます。ここでイベントハンドラを変更できます。


Associating an event with an existing event handler
Associating an event with an existing event handler1061006

Section topics	参照

複数のコンポーネントイベントを処理するイベントハンドラを記述すると，コードも再利用できます。たとえば，メニューコマンドとそれに対応するスピードバーボタンの両方から呼び出せる汎用のイベントハンドラが考えられます。このようなイベントハンドラを 1 つ書けば，このハンドラにほかのイベントを関連付けるのは簡単です。

既存のイベントハンドラに新しいコンポーネントイベントを関連付ける手順は次のとおりです。

1.	イベントハンドラと関連付けるコンポーネントをフォームで選択します。

2.	オブジェクトインスペクタの［イベント］ページを表示し，コードを結び付けるイベントを選択します。

3.	イベント値の横の下矢印をクリックし，既存のイベントハンドラのリストを開きます。
リストには，このフォームのイベントハンドラの中で，選択したイベントに割り当て可能なものだけが表示されます。

4.	リストのイベントハンドラ名をクリックして選択します。

これで，このイベントハンドラに記述されたコードと選択したコンポーネントイベントが関連付けられます。

メモ	Delphi では，共有されているハンドラに関連付けられたすべてのコンポーネントイベントごとにイベントハンドラコードが複製されるわけではありません。コードエディタに表示される共有ハンドラのコードは 1 つだけですが，このコードは関連付けられたすべてのコンポーネントイベントから呼び出されます。


Using the Sender parameter
Using the Sender parameter1061007

Section topics	参照

複数の異なるコンポーネントに，どのコンポーネントを呼び出すかによって別のことをするハンドラを共有させることができます。それには，if..then..else 文で Sender パラメータを使います。

イベントハンドラの Sender パラメータは，どのコンポーネントがイベントを受信し，その結果ハンドラを呼び出したかを Delphi に知らせます。

次のコードは，モード付きダイアログボックスのキャプションにアプリケーションのタイトルを表示するか，なにも表示しないかを記述しています。OnClick イベントが，Button1 により受信されたか，同じイベントハンドラを使って別のボタンにより受信されたかによってどちらかに決まります。

procedure TMain1.Button1Click(Sender: TObject);

begin

if Sender = Button1 then

AboutBox.Caption := 'About ' + Application.Title

else AboutBox.Caption := '';

AboutBox.ShowModal;

end;

プログラムを再び実行して Button1 をクリックすると，［About］ボックスのキャプションにアプリケーションのタイトルが表示されます。このイベントハンドラに関連付けられている他のコンポーネントをクリックすると，［About］ボックスは開きますが，アプリケーションのタイトルは表示されません。


Displaying and coding shared events
Displaying and coding shared events1061008

Section topics	参照

イベントハンドラを共有する別の方法があります。コンポーネント間に共通なイベントがある場合，それらのコンポーネントを選択すると，オブジェクトインスペクタには共通のイベントが表示されます。この共通のイベントを 1 つ選択し，このイベントに新しいイベントハンドラを作成するか，既存のイベントハンドラを選択します。すると，このイベントハンドラはすべての選択したコンポーネントで使えるようになります。

共通のイベントを表示する手順は次のとおりです。

1.	表示する共通のイベントを持つすべてのコンポーネントをフォームで選択 (〔Shift〕を押しながらクリック) します。

2.	オブジェクトインスペクタの［イベント］ページでイベントを選択します。
オブジェクトインスペクタでは，すべての選択したコンポーネントに共通のイベントだけが表示されます。なお，表示されるイベントは現在のフォームにあるものだけです。

共通のコンポーネントイベントを既存のイベントハンドラに関連付ける手順は次のとおりです。

1.	共有イベントハンドラと関連付けるすべてのコンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページで，イベントを選択します。
オブジェクトインスペクタでは，選択したコンポーネントに共通のイベントだけが表示されます。

3.	イベントの横にあるドロップダウンリストで，既存のイベントハンドラを選択し〔Enter〕を押します。
選択したコンポーネントのいずれかで指定のイベントを受け取ると，選択したイベントハンドラが呼び出されます。

イベントの共有イベントハンドラを作成する手順は次のとおりです。

1.	共有イベントハンドラを作成するすべてのコンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページでイベントを選択します。

3.	新しいイベントハンドラの名前を入力して〔Enter〕を押すか，ハンドラ列をダブルクリックして Delphi に名前を生成させます。
Delphi は，コードエディタにイベントハンドラを作成し，カーソルを begin..end ブロック内に配置します。
イベントハンドラに名前を指定しないと，Delphi はコンポーネントを選択した順序に基づいてイベントハンドラに名前を付けます。たとえば，複数のボタンに共有イベントハンドラを作成すると，Delphi ではイベントハンドラに Button<n>Click の形式の名前を付けます。Button<n> はイベントハンドラを共有するために選択した最初のボタンを表します。

4.	コンポーネントで指定のイベントが発生したときに実行するコードを入力します。


Modifying a shared event handler
Modifying a shared event handler1061009

Section topics	参照

複数のコンポーネントで共有するイベントハンドラを変更する方法は，既存のイベントハンドラの場合とほぼ同じです。ただし，共有イベントハンドラを変更すると，このハンドラを呼び出すすべてのコンポーネントイベントにおいて変更されることに注意してください。

共有イベントハンドラを変更する手順は次のとおりです。

1.	変更するハンドラを呼び出すイベントを持つコンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページで，イベントハンドラの名前をダブルクリックします。

3.	このハンドラをコードエディタで変更します。
これで，このハンドラを共有するコンポーネントのいずれかで共有イベントを受け取ると，変更したコードが呼び出されます。

フォームとプロジェクトの共有についての詳細は「オブジェクトの共有」を参照してください。


Deleting event handlers
Deleting event handlers1061010

Section topics	参照

コンポーネントを削除すると，Delphi はコンポーネントの参照をフォームの型宣言から除去します。しかし，コンポーネントを削除しても関連付けられたメソッドはユニットファイルから削除されません。すでに述べたように，これはフォームのほかのコンポーネントで，これらのメソッドを呼び出す場合があるからです。メソッド宣言とメソッド自体の両方がユニットファイル内にある場合は，アプリケーションを以前のとおりに実行できます。メソッドを削除してもメソッドの宣言を削除しないと，Delphi は「forward または external 宣言されたフォーム名 . メソッド名が見つかりません .」というエラーメッセージを表示し，メソッド自体を置き換えるか，またはメソッドのコードとともに宣言も削除することを要求します。メソッドを使う必要がある場合はメソッドを新しく置き換え，メソッドを使わない場合は宣言も削除します。

イベントハンドラは明示的に削除することも Delphi に削除させることもできます。

イベントハンドラを手作業で削除するには，イベントハンドラのすべてのコードと宣言を除去します。

イベントハンドラを Delphi に削除させるには，イベントハンドラ内のすべての begin..end ブロック内のコードを (コメントも含めて) 除去します。このハンドラは，プロジェクトをコンパイルするか保存すると除去されます。


Associating menu events with code
Associating menu events with code1061011

Section topics	参照

メニューデザイナでアプリケーションメニューをビジュアルに設計できますが，メニューを最終的に使えるようにするのはソースコードです。各メニューのコマンドが OnClick イベントに応答できるようにしなければなりません。またプログラムの条件に応じてメニューを動的に変更しなければならない場合もあります。

以降の各節では，コードをメニューイベントに関連付ける方法について説明します。実行中のアプリケーションでメニューを動的に変更する方法を示すコード例については，「MDI アプリケーションの作成」を参照してください。


Menu component events
Menu component events1061012

Section topics	参照

MainMenu コンポーネントは，関連付けられたイベントがないという点でほかの大部分のコンポーネントと異なります。メインメニューの各項目のイベントにアクセスするにはメニューデザイナを使います。

一方，PopupMenu コンポーネントには OnPopup イベントがあります。このイベントが必要なのは，ポップアップメニューにはメニューバーがなく，ユーザーがメニューを開かないと OnClick イベントを使えないためです。

Handling menu item events1061013

メニューコンポーネントの各メニュー項目には，イベントとして OnClick が 1 つだけあります。メニュー項目の OnClick イベントに関連付けられたコードは，実行中のアプリケーションでユーザーがそのメニュー項目を選択したときに実行されます。メニュー項目を選択するには，メニューコマンドをクリックするか，アクセラレータまたはショートカットキーを使います。

メニュー項目のイベントハンドラを作成する手順は次のとおりです。

1.	メニューデザイナウィンドウにあるメニュー項目をダブルクリックします。

2.	begin..end ブロック内に，ユーザーがこのメニューコマンドをクリックしたときに実行するコードを入力します。

フォームに表示されるメニュー項目のイベントハンドラも次のようにして簡単に生成できます。ただし，ポップアップメニュー項目は，設計時にはフォームに表示されないので，この方法は使えません。

フォームに表示されるメニュー項目からイベントハンドラを作成するには，メニューコンポーネントではなくそのメニュー項目をクリックします。たとえば，フォームの［ファイル］メニューにメニュー項目［開く］がある場合，この［開く］をクリックするだけで，関連付けられたイベントハンドラを作成し，開くことができます。

この手順を使えるのは，リスト内のメニュー項目だけです。メニューバーのメニュー項目には使えません。メニューバーのメニュー項目をクリックすると，メニューが開き，サブメニュー項目が表示されます。

Associating a menu item with an existing event handler1061014

メニュー項目に既存のイベントハンドラを関連付けることもできます。つまり，同じコードを繰り返し作成しないで再利用できます。

メニュー項目に既存の OnClick イベントハンドラを関連付ける手順は次のとおりです。

1.	メニューデザイナウィンドウのメニュー項目を選択します。

2.	オブジェクトインスペクタの［プロパティ］ページで，メニュー項目の Name プロパティに値が設定されていることを確認します。

3.	オブジェクトインスペクタの［イベント］ページで，OnClick の横にある下矢印をクリックして，以前に作成したイベントハンドラのリストを表示します。
このフォームの OnClick イベントに作成したイベントハンドラだけが，リストに表示されます。

4.	リストのイベントハンドラ名をクリックして選択します。
このイベントハンドラに作成されたコードが，選択したメニュー項目に関連付けられます。


See also1061015

コードエディタの使い方

イベントハンドラ内のブロック

コードの実行経路の制御


Working with the Code editor
Working with the Code editor1053001

Section topics	参照

コードエディタを使うと，ソースコードを簡単に表示したり変更したりできます。

新しいプロジェクトを開くと，最初のフォームユニットファイルのページがコードエディタ内で自動的に生成されます。プロジェクトで新しいフォームやユニットなどのファイルを追加すると，関連付けられたソースコードまたは他のデータを含む，新しいページがコードエディタに追加されます。現在のプロジェクトにないファイルを開くと，そのファイルの独自のページも表示されます。さらに，コードエディタでは，すべてのテキストファイルを開いて表示したり変更することもできます。

Delphi コードエディタは，以下の機能を持つ，カスタマイズ可能な高機能テキストエディタです。

構文強調表示

多段階のグループ単位の取り消し

4 種類の定義済みエディタ設定：標準，IDE クラシック，BRIEF，Epsilon

言語要素の状況感知型へルプ

この章では，コードエディタの主な機能を紹介します。まず，コードエディタで複数のファイル間を移動する方法，ソースコードとフォームデザインウィンドウを切り替える方法を解説し，さらに，以下のトピックを説明します。

コンポーネントをコードとして表示する方法

テキスト，オブジェクト，記号等の検索

コードエディタのカスタマイズ


Viewing files in the Code editor
Viewing files in the Code editor1053002

Section topics	参照

コードエディタでは，エディタウィンドウの上部にあるタブでファイルを表します。ですから，適当なタブをクリックするだけで，エディタで開いているファイル同士を簡単に切り替えることができます。タブをクリツクすると，エディタのページにそのファイルが表示されます。

コードエディタの特定のファイルを表示するには，以下の 7 つの方法のどれかを使います。

［ファイル(F)｜開く(O)］を選択して既存のファイルを開く

すでに開いているファイルの場合，表示したいファイルのタブをクリックする

エディタで現在開かれているファイルの間で前方に移動するには〔Ctrl〕+〔Tab〕，逆方向に移動するには〔Shift〕+〔Ctrl〕+〔Tab〕を押す

［表示(V)｜ユニット(U)］を選択して，［ユニットの表示］ダイアログボックスを開き，表示したいユニットを選択する

スピードバーのボタンを使って，現在のフォームとそれに関連付けられたユニットを切り替えるか，［ユニットの表示］ダイアログボックスを開く

エディタ内のファイル名にカーソルを置き，右クリックしてから［このファイルを開く(F)］を選択する

［表示(V)｜プロジェクトマネージャ(P)］を選択し，プロジェクトウィンドウ内のユニットをダブルクリックする

編集ウィンドウのコントロールメニューボックスをダブルクリックしてコードエディタを閉じると，開かれていたプロジェクトのファイルが｢すべて｣閉じます。1 ページだけを閉じるには，コードエディタのスピードメニューから［このページを閉じる(C)］を選択します。


Viewing the associated form
Viewing the associated form1053003

Section topics	参照

コードエディタのファイルを表示するときは，現在のファイルに関連付けられているフォームまたは別のフォームにいつでも戻ることができます。

フォームに戻るには，以下の 3 つの方法のどれかを使います。

フォームのうちでコードエディタの下に見えている部分をクリックする

［表示(V)｜フォーム(F)］を選択して，［フォームの表示］ダイアログボックスを開き，表示したいフォームを選択する

スピードバーのボタンを使って，現在のフォームを表示するか，［フォームの表示］ダイアログボックスを開く

〔F12〕を押す (切り替えボタンになっている)

メモ	コードエディタに現在表示されているコードに関連付けられたフォーム以外のフォームを表示すると，そのフォームに合わせてコードのページが変更されます。このためコードエディタに戻ったときに，前に表示されていたコードが表示されない場合があります。


Viewing components as code in the editor
Viewing components as code in the editor1053004

Section topics	参照

フォームにコンポーネントを追加すると，Delphi は，そのコンポーネントのインスタンス変数を生成し，フォームの型宣言に追加します。同様に，コンポーネントを削除すると，Delphi は，そのコンポーネントに対応する型宣言をソースコードから除去します。コードエディタから，これに相当するコードが追加されたり除去されるのを見ることができます。

Delphi が生成するコードをその場で表示する手順は次のとおりです。

1.	フォームのタイトルバーをクリックし，コードエディタ全体が見える位置までドラッグすることによって，フォームを移動してフォームと編集ウィンドウの両方が見えるようにします。

2.	コードエディタをフォームの型宣言部分が見えるまでスクロールします。

3.	コードエディタで何が起きるかを見ながら，フォームにコンポーネントを追加します。

4.	コードエディタを見ながら，コンポーネントを削除します。

メモ	Delphi は，ユーザーが削除したコンポーネントに関連付けられたイベントハンドラまたはメソッドを除去しません。というのは，このイベントハンドラまたはメソッドが，フォームのほかのコンポーネントから呼び出される可能性があるからです。メソッド宣言とメソッド自体の両方がユニットファイルに残っている限り，プログラムを実行することができます。宣言を削除せずにメソッドを削除すると，Delphi がエラーメッセージを生成します。

メモ	Delphi が生成したコードは編集してはいけません。編集するのは，自分で作成したコードに限ってください。


Code editor Context menu
Code editor Context menu1053005

Section topics	参照

コードエディタ内で右クリツクすると，スピードメニューにアクセスできます。スピードメニューには，使用頻度の高い編集コマンド，デバッグコマンド，Delphi 開発環境内を移動するためのコマンドがあります。スピードメニューに含まれるコマンドの詳細については，スピードメニューでメニュー項目を選択して〔F1〕を押してください。

コードエディタのコンテキストメニュー


Searching in the Code editor
Searching in the Code editor1053006

Section topics	参照

［検索(S)］メニューを使って，コードエディタ内で特定のテキスト，オブジェクト，ユニット，変数またはシンボルを検索します。

［検索(S)］は，特定のテキストを検索します。現在のファイル以外のファイルを検索したい場合は，［ファイルを検索］ページを使って，すべての開いているファイル，プロジェクトのすべてのファイル，名前の付いたディレクトリのどれを検索するのか指定します。

［ファイルを検索］は，［テキストの検索］ダイアログボックスの［ファイルを検索］ページだけを開きます。

［置換(R)］は，特定のテキストを検索し，新しいテキストに置換します。

［次を検索(S)］は検索を繰り返します。

［インクリメンタルサーチ(I)］は，入力するテキストごとに検索します。

［指定行に移動(G)］は，カーソルを特定の行番号へ移動します。

［検索(S)］メニューのコマンドの詳細については，コマンドを選択して〔F1〕を押してください。


Customizing the editor
Customizing the editor1053007

Section topics	参照

Delphi コードエディタをカスタマイズするには，［ツール(T)｜環境オプション(O)］を選択します。

［環境オプション］ダイアログボックスでは，以下の方法でエディタの動作と外見をカスタマイズすることができます。

デフォルトエディタを選択し，キーマッピングをカスタマイズする

設定する色を選択する

表示オプションとファイルオプションを指定する

コーディング支援オプションを選択する


Selecting a default editor
Selecting a default editor1053008

Section topics	参照

エディタのデフォルトキーマッピングを選択するには，［エディタ］ページにある［エディタスピード設定］ドロップダウンリストを使います。このオプションを，表で説明します。

オプション	自動設定される項目
デフォルトキーマッピング	オートインデントモード，挿入モード，スマートタブ，バックスペースアンインデント，グループ単位の取り消し，ブロックの置き換え，構文強調を表示
DOS IDE	オートインデントモード，挿入モード，スマートタブ，バックスペースアンインデント，タブ間のカーソル移動，グループ単位の取り消し，ブロックの保存，構文強調を表示
BRIEF エミュレーション	オートインデントモード，挿入モード，スマートタブ，バックスペースアンインデント，タブ間のカーソル移動，EOF 以降へのカーソル移動，行末の空白の保存，BRIEF 型正規検索表現，コピー/切り取りを常に有効，構文強調を表示
Epsilon エミュレーション	オートインデントモード，挿入モード，スマートタブ，バックスペースアンインデント，タブ間のカーソル移動，グループ単位の取り消し，ブロックの置き換え，構文強調を表示
デフォルトキーマッピングを選択してから，［エディタ］ページのほかのオプションを使ってコードエディタの動作をカスタマイズすることができます。このページのオプションの詳細については，〔F1〕を押すか，ダイアログボックスで［ヘルプ］をクリックしてください。


Choosing color settings for the editor
Choosing color settings for the editor1053009

Section topics	参照

コードのさまざまな要素をコードエディタ内でどのように表示するかを指定するには，［環境オプション］ダイアログボックスの［色］ページを使います。［色］ページの下側のサンプルボックスでは，設定がどのように表示されるかが示されます。

［表示色のスピード設定］を使うと，定義済みの色の組合せを使ってコードエディタの表示を設定できます。また，定義済みの色のセットを選択した後で，コードの表示をさらにカスタマイズすることができます。［文法要素］リストボックスに一覧表示されたものであれば，どれでも前景色，背景色，テキスト属性を指定できます。


Specifying display and file options
Specifying display and file options1053010

Section topics	参照

コードエディタの表示オプションとフオントオプションをカスタマイズするには，［環境オプション］ダイアログボックスの［表示］ページを使います。［例］に，選択されたフオントが表示されます。新しい設定は，［OK］をクリックしたときに有効になります。

たとえば，エディタを全画面表示で開いたり，BRIEF 風カーソル形状を使ったり，バックアップファイルを作成するように設定することができます。また，ガターとマージンを表示するか，幅をどのように表示するか指定できます。使用可能なオプションの詳細については，ダイアログボックス内の［ヘルプ］ボタンをクリックしてください。


What kind of help do you want while coding?
What kind of help do you want while coding?1053011

Section topics	参照

コードを記述するとき，状況感知型ポップアップウインドウからへルプを選択できます。それには，［環境オプション］ダイアログボックスの［支援機能］ページで，次の中から選択できます。

オプション	使用できるとき
コード補完	ピリオドの付いたクラス名を入力したとき，ダイアログボックスのポップアップにはそのクラスに適したプロパティ，メソッド，およびイベントのリストが表示される。コードに記述したい項目をここから選択する 割り当てられた文を入力し，〔Ctrl〕+〔Space〕を押すと，表示される変数に有効な引数のリストが表示される。コードに記述したい引数を選択する
宣言表示	開いたカッコを付けてメソッド呼び出しを入力すると，リストボックスがポップアップ表示され，メソッドの引数の構文が表示される
コードテンプレート	〔Ctrl〕+〔J〕を押してコードテンプレートのリストを表示すると，共通プログラミング文がコードに自動的に挿入できる。このリストは編集や追加ができる
式評価	［プロジェクトオプション］ダイアログボックスの［コンパイラ］ページで［デバッグ情報(D)］をチェックしてコンパイルしているとき，コンパイルプロセスが停止した場合は，変数にカーソルを置いて変数の値を表示できる この機能を使用するときは［プロジェクトオプション］ダイアログボックスの［コンパイラ］ページの［最適化をおこなう(O)］をチェックしない方がよい。そうしないと，この機能はローカル変数の値を表示しないことがある
詳細は，［支援機能］ページで［ヘルプ］ボタンをクリックしてください。


See also1053012


Using packages
Using packages1072001

Section topics	参照

Delphi のパッケージは，特別にコンパイルされたダイナミックリンクライブラリです。実行時パッケージを使うと，アプリケーションの中でのコードの共有，実行可能サイズの縮小，システムリソースの節約ができます。設計時パッケージを使うと，IDE のコンポーネントの処理が簡単になり，カスタムコンポーネントのための特別なプロパティエディタが作成できます。1 つのパッケージは，設計時と実行時の両方で機能できます。また，実行時パッケージを呼び出すと設計時パッケージが機能することもあります。

Delphi ビジュアルコンポーネントライブラリ (VCL) 自体はパッケージに分割され，含まれるコードをアプリケーションの間で共有することができます。たとえば，Delphi の大部分で一般的に使われるコンポーネントは，VCL30.DPL (Delphi パッケージライブラリ) と呼ばれるパッケージの中にあります。アプリケーションを作成するたびにそのアプリケーションが VCL30.DPL を使うことを指定できます。このようにして作成したアプリケーションをコンパイルすると，その実行可能イメージにはアプリケーションに固有のコードとデータだけが含まれます。共通コードは VCL30.DPL に含まれています。インストールされている複数のパッケージアプリケーションを使うコンピュータの場合，VCL30.DPL のコピーだけが必要です。 VCL30.DPL は，すべてのアプリケーションに共有される，Delphi の統合開発環境 (IDE) そのものです。

VCL パッケージおよびユーザーやサードパーティ開発者の作成したカスタムパッケージの中から選択して，Delphi アプリケーションを構築することができます。

この章では，以下の方法を説明します。

アプリケーションでのパッケージの使用

パッケージの作成と編集

パッケージのコンパイル

パッケージの開発と配布


Why use packages?
Why use packages?1072002

Section topics	参照

実行時パッケージはオプションで使いますが，従来のプログラミングよりもいくつかの利点があります。再利用するコードを実行時パッケージでコンパイルすると，アプリケーションでそのコードを共有することができます。たとえば，「Delphi IDE 自体を含む」すべてのアプリケーションは，パッケージを使って標準コンポーネントにアクセスできます。その結果，システムリソースとディスク記憶域の両方が劇的に節約されます。さらに，パッケージを使うと，構築ごとにコンパイルされるのはアプリケーションに固有のコードだけなので，より速いコンパイルが可能です。

IDE にカスタムコンポーネントを追加したい場合には，設計時パッケージを使用しなければなりません。


Using runtime packages
Using runtime packages1072003

Section topics	参照

Delphi のアプリケーションを使うと，実行時パッケージを開発できます。パッケージは，Delphi に付属のものでも，ユーザー独自のカスタムパッケージでもかまいません (「パッケージの作成」参照)。

パッケージを使うアプリケーションを実行するには，アプリケーションの .EXE ファイルとアプリケーションが使うすべてのパッケージ (.DPL) ファイルの両方がコンピュータに含まれている必要があります。アプリケーションを開発するとき，ユーザーは，必要な DPL の正しいバージョンを使うようにしてください。

アプリケーションで実行時パッケージを使用する方法は次のとおりです。

1.	IDE にプロジェクトを読み込むかまたは作成します。

2.	［プロジェクト(P)｜オプション(O)］を選択します。

3.	［パッケージ］タブを選択します。

4.	［実行時パッケージを使って構築(B)］チェックボックスを選択して，編集ボックスに 1 つまたは複数のパッケージ名を入力します (インストールされているパッケージに関連付けられた実行時パッケージのリストはすでに編集ボックスに表示されています)。既存のリストにパッケージを追加するには，編集ボックスの隣にある［追加(A)］ボタンをクリックして，［実行時パッケージの追加］ダイアログボックスで新しいパッケージの名前を入力します。または，［パッケージ名(P)］編集ボックスの隣の［参照(B)］ボタンをクリックしパッケージを選択します。

メモ	［実行時パッケージの追加］ダイアログボックスの［検索パス(S)］ボックスを変更する場合，［ツール(T)｜環境オプション(O)］の環境オプションダイアログの［ライブラリ］タブにある［ライブラリパス(B)］を変更することになります。

パッケージ名にはファイル拡張子は必要ありません。［実行時パッケージ］編集ボックスに直接入力する場合，複数のファイル名はセミコロンで区切って次のように入力します。

VCL30;VCLDB30;VCLDBX30

［実行時パッケージ(U)］編集ボックスに表示されているパッケージは，コンパイル時に自動的にアプリケーションにリンクされます。重複するパッケージ名があると無視されます。編集ボックスが空の場合，アプリケーションはパッケージを含まずにコンパイルされます。実行時パッケージは現在のプロジェクトだけに選択されます。新しいプロジェクトに現在の選択を自動的にデフォルト設定するには，ダイアログボックスの一番下にある［デフォルト］チェックボックスを選択します。

メモ	パッケージでアプリケーションを作成するときは，元の Delphi ユニットの名前をソースファイルの uses 節に含む必要があります。たとえば，以下のように始まるメインフォームのソースファイルがあるとします。

unit MainForm;

interface

uses

  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

この例で参照する各ユニットは VCL30 パッケージに含まれています。それでも，VCL30 のこれらの参照ユニット名を uses 節に含む必要があります。そうしないと，たとえ VCL30 をアプリケーションで使ってもコンパイルエラーとなります。


Deciding which runtime packages to use
Deciding which runtime packages to use1072004

Section topics	参照

いくつかのコンパイル済み実行時パッケージが Delphi と一緒にインストールされます。このパッケージは，基本の Object Pascal コードと VCL をサポートします。Delphi の従来のバージョンでは，これらのパッケージが提供する機能を使うために，コンポーネントライブラリの完全なコピーを各アプリケーションにリンクしていました。

VCL30 パッケージには，もっとも一般的に使われるコンポーネント，システム機能，Windows インターフェース要素が含まれています。これには，データベースや Windows 3.1 コンポーネントは含まれず，別のパッケージで提供されます。以下の表は，Delphi と一緒にインストールされる実行時パッケージおよびそれに含まれるユニットの一覧です。

パッケージ	ユニット
VCL30.DPL	Ax，Buttons，Classes，Clipbrd，Comctrls，Commctrl，Commdlg，Comobj，Comstrs，Consts，Controls，Ddeml，Dialogs，Dlgs，Dsgnintf，Dsgnwnds，Editintf，Exptintf，Extctrls，Extdlgs，Fileintf，Forms，Graphics，Grids，Imm，IniFiles，Isapi，Isapi2，Istreams，Libhelp，Libintf，Lzexpand，Mapi，Mask，Math，Menu，Messages，Mmsystem，Nsapi，Ole2I，Oleconst，Olectnrs，Olectrls，Oledlg，Penwin，Printers，Proxies，Registry，Regstr，Richedit，Shellapi，Shlobj，Stdctrls，Stdvcl，Sysutils，Tlhelp32，Toolintf，Toolwin，Typinfo，Vclcom，Virtintf，Windows，Wininet，Winsock，Winspool，Winsvc
VCLX30.DPL	Checklst，Colorgrd，Ddeman，Filectrl，Mplayer，Outline，Tabnotbk，Tabs
VCLDB30.DPL	Bde，Bdeconst，Bdeprov，Db，Dbcgrids，Dbclient，Dbcommon，Dbconsts，Dbctrls，Dbgrids，Dbinpreq，Dblogdlg，Dbpwdlg，Dbtables，Dsintf，Provider，SMintf
VCLDBX30.DPL	Dblookup，Report
DSS30.DPL	Mxarrays，Mxbutton，Mxcommon，Mxconsts，Mxdb，Mxdcube，Mxdssqry，Mxgraph，Mxgrid，Mxpivsrc，Mxqedcom，Mxqparse，Mxqryedt，Mxstore，Mxtables，Mxqvb
INET30.DPL	Cgiapp，Copyprsr，Httpapp，Isapiapp，Masks，Scktcomp，Syncobjs，Webconst
INETDB30.DPL	Dbweb
QRPT30.DPL	Qr2const，Qrabout，Qralias，Qrctrls，Qrdatasu，Qrexpbld，Qrextra，Qrprev，Qrprgres，Qrprntr，Qrqred32，Quickrpt
TEE30.DPL	Arrowcha，Bubblech，Chart，Ganttch，Series，Teeconst，TeeFunci，TeEngine，Teeprocs，Teeshape
TEEDB30.DPL	Dbchart，Qrtee
IBEVNT30.DPL	Ibctrls，Ibevnts，Ibproc32，Ibreg
パッケージを使ってクライアント/サーバーデータベースアプリケーションを作成する場合，少なくとも VCL30 と VCLDB30 の 2 つのパッケージが必要です。アプリケーションでアウトラインコンポーネントを使いたい場合には，このほかに VCLX30 も必要です。

メモ	なお VCL30 は VCLDB30 の requires 節で参照されるため［プロジェクトオプション］ダイアログボックスで VCL30 をリストに入力する必要はありません (「requires 節」参照)。VCL30 がリストに含まれているか否かにかかわらず，アプリケーションは同じようにコンパイルされます。


Using design-time packages
Using design-time packages1072005

Section topics	参照

Delphi では，すべてのコンポーネントは IDE にパッケージとしてインストールされます。また，パッケージは，カスタムコンポーネントの特別なプロパティエディタの作成にも使われます。

Delphi は，IDE に事前にインストールされた以下の設計時パッケージと一緒にインストールされます。

パッケージ	コンポーネントパレットのページ
DCLSTD30.DPL	Standard，Additional，System，Win32，Dialogs
DCLTEE30.DPL	Additional (TChart コンポーネント)
DCLDB30.DPL	Data Access，Data Controls
DCL31W30.DPL	Win 3.1
DCLNET30.DPL DCLISP30.DPL	Internet
DCLSMP30.DPL	Sample
DCLOCX30.DPL	ActiveX
DCLQRT30.DPL	Qreport
DCLDSS30.DPL	Decision Cube
IBEVNT30.DPL	Samples (IBEventAlerter コンポーネント)
これらの設計時パッケージは実行時パッケージを呼び出すとその require 節で参照されて機能します (「require 節」参照)。たとえば，DCLSTDLIB は VCL30 を参照します。DCLSTDLIB 自体には，ほとんどの標準コンポーネントをコンポーネントパレットで使用可能にする追加機能が含まれています。

プロジェクトで使う設計時パッケージを選択する方法は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選び，［パッケージ］タブを選択します。

2.	［設計時パッケージ］リストボックスで，使いたいパッケージにチェックマークを付けます。不要のパッケージはチェックをはずします。

3.	パッケージをリストに追加するには，リストボックスの下にある［追加(A)］ボタンをクリックします。

4.	この選択を将来のプロジェクトのデフォルトにするには，ダイアログボックスの下隅にある［デフォルト］チェックボックスをチェックします。

5.	［OK］をクリックします。


Installing your own components
Installing your own components1072006

Section topics	参照

コンポーネントパレットから使用できるコンポーネントを追加したい場合，独自のコンポーネントパッケージやサードパーティ開発者のコンポーネントパッケージをインストールできます。その方法については，「Delphi にコンポーネントを追加する」を参照してください。


Creating and editing packages
Creating and editing packages1072007

Section topics	参照

パッケージソースファイルには，型，データ，手続き，および関数の宣言部は含まれません。含まれるものは次のとおりです。

パッケージの名前

新しいパッケージに必要な，またはリンクされる，その他のパッケージのリスト

パッケージがコンパイルされるときに含まれ，結合されるユニットファイルのリスト。パッケージは本質的には，コンパイルされた DPL の機能を含むこれらのソースコードユニットのラッパーです。

.DPK 拡張子で終わるパッケージソースファイルは，［パッケージ］エディタで作成されます。


Creating a package
Creating a package1072008

Section topics	参照

ここで概説する手順についての詳細は，「パッケージの規則」を参照してください。

パッケージを作成するには，次の手順にしたがいます。

1.	IDE にプロジェクトをロードまたは作成します。

2.	［ファイル(F)｜新規作成(N)］を選択して［パッケージ］アイコンを選択し，［OK］をクリックします。

3.	［パッケージの新規作成］ダイアログボックスで，ファイル名と (オプションで) 説明を入力します。名前にディレクトリパスを含めることができます。ディレクトリパスが含まれないと，パッケージは現在のディレクトリに入ります。ファイル/ディレクトリ選択を行う［パッケージ名］ダイアログを開くには，［参照(B)］ボタンをクリックします。［パッケージの新規作成］ダイアログにファイル名を直接入力すると，自動的に .DPK 拡張子が追加されます。

4.	［OK］をクリックして，［パッケージ］エディタを開きます。

5.	［内容］タブを選択し，［追加］スピードボタンをクリックします。

6.	［追加］ダイアログボックスが開いたら，既存のユニットファイルをパッケージの contains 節に追加したり，既存コンポーネントの下位の新規コンポーネントを作成したり，あるいは ActiveX コンポーネントをインポートしたりできます。

パッケージの contains 節にユニットファイルを追加するには，［ユニットの追加］タブを選び，［ユニットファイル名(U)］編集ボックスにファイル名を入力します。ファイル名と一緒にディレクトリパス名全部を指定するか，または［検索パス(S)］編集ボックスで検索パスを編集できます。検索パスを編集する場合，Delphi のグローバルなライブラリパスが変更されます。パッケージにもっとユニットファイルを追加するには，［OK］をクリックして［追加］ダイアログを閉じてから，パッケージエディタで［追加］スピードボタンを再びクリックします。

新規コンポーネントを作成するには，［コンポーネントの新規作成］タブを選択します。新規コンポーネントの［クラス名(C)］，［上位クラス(A)］，コンポーネントの宣言が記述される［ユニットファイル名(U)］，新規コンポーネントを表示する［パレットページ名(P)］を入力します。ファイル名と一緒にディレクトリパス名全部を指定するか，または［検索パス(S)］編集ボックスで検索パスを編集できます。検索パスを編集する場合，Delphi のグローバルなライブラリパスが変更されます。

ActiveX コンポーネントをインポートするには，［ActiveX コンポーネントの取り込み］タブを選び，登録されているコンポーネントをリストボックスから選択します。新規コンポーネントを登録するには［追加(A)］をクリックし，コンポーネントの登録を解除するには［削除(R)］をクリックします。

7.	パッケージエディタで，［必須］タブをクリックすると，編集しているパッケージの requires 節にあるその他のパッケージのリストが表示されます。VCL30 はデフォルトで表示されます。requires 節にパッケージを追加します。

8.	［オプション］スピードボタンをクリックして，［情報］タブをクリックします。

［使い方の指定(U)］で，［設計時パッケージ(D)］または［実行時パッケージ(R)］，あるいはその両方をチェックします。これらのオプションのうち1 つだけを選択すると，$RUNONLY または $DESIGNONLY コンパイラ指令がオンになります (「コードにパッケージ独自のコンパイラ指令を挿入する」参照)。IDE にインストールできない (ただし，他の設計時パッケージで呼び出せる) 設計時パッケージを作成するには，チェックマークをとって両方のチェックボックスの選択を解除します。

［構築方法の指定］で，［必要に応じて再構築(N)］または［手動で再構築(E)］を選択します。［手動で再構築］を選択すると，-Z ($IMPLICITBUILD OFF) コンパイラスイッチがオンになり，パッケージが暗黙に再コンパイルされるのを防ぎます (「コマンドラインコンパイラの使い方」参照)。

9.	［OK］をクリックして［パッケージオプション］ダイアログを閉じ，変更を保存します。

10.	パッケージエディタで，［コンパイル］スピードボタンをクリックして，パッケージをコンパイルします。

［コンパイル］スピードボタンをクリックすると，パッケージが DPL にコンパイルされますが，パッケージソース (.DPK) ファイルは保管されません。.DPK ファイルを保管するには，［パッケージの上書き保存(S)］を右クリックして選択するか，または Delphi のメインメニューバーから［ファイル(F)｜保存(S)］を選択します。


Editing a package in the Package editor
Editing a package in the Package editor1072009

Section topics	参照

パッケージエディタで既存のパッケージを開くには，次の方法があります。

［ファイル(F)｜開く(O)］(または［ファイル(F)｜開き直す(R)］) を選択して，.DPK ファイルを選択します。

［コンポーネント(C)｜パッケージのインストール(P)］を選択して，設計時パッケージリストからパッケージを選び，［編集］ボタンをクリックします。

［コンポーネント(C)｜コンポーネントのインストール］を選択して，［既存パッケージへ］タブをクリックします。次にパッケージとユニットファイルを選択して，パッケージの contains 節に追加します。

パッケージエディタが開いているとき，［必須］タブをクリックします。次にリストからパッケージを1 つ選択して右クリックし，［必要なパッケージを表示(P)］を選択します。

［ファイル(F)｜開く(O)］を選択してパッケージを開き，.DPL ファイルを選択することもできます。ただし，.DPL を選択していても，パッケージエディタは常に .DPK ファイルを開こうとします。.DPK ファイルが見つからない場合，パッケージエディタは，.DPL ファイルを読み取り専用ベースで開くことができます。この場合，パッケージを .DPK として再保存し，後で編集します。

パッケージエディタの［内容］ページには，現在のパッケージに含まれるユニットファイルのリストが表示されます。適切なスピードボタンをクリックすると，ファイルの追加や削除ができます。コードエディタでユニットファイルを開くには，ファイルを選択して右クリックし，［ユニットの表示(U)］を選択します。

［必須］ページには現在のパッケージに必要な (リンクされた) 他のパッケージのリストが表示されます。適切なスピードボタンをクリックすると，ファイルの追加や削除ができます。新しいパッケージエディタで必要なパッケージの 1 つを開くには，パッケージを選択して右クリックし，［必要なパッケージを表示］を選択します。

［オプション］スピードボタンを使うと，パッケージの説明を編集したり，コンパイラおよびライブラリオプションを設定できます。


Editing package source files manually
Editing package source files manually1072010

Section topics	参照

プロジェクトファイルと同様に，パッケージソースファイルも，ユーザーの与えた情報に基づいて Delphi が作成します。また，プロジェクトファイルと同様に，パッケージソースファイルも手作業で編集できます。パッケージソースファイルは，Object Pascal ソースコードを含む他のファイルとの混同を避けるために .DPK (Delphi パッケージ) 拡張子を付けて保存する必要があります。

コードエディタでパッケージソースファイルを開く方法は，次のとおりです。

1.	パッケージエディタでパッケージを開きます。

2.	パッケージエディタを右クリックして，［パッケージソースを表示］を選択します。

package ヘッダーはパッケージの名前を指定します。

requires 節は，現在のパッケージで使われる他の外部パッケージのリストを表示します。パッケージが他のパッケージを参照しない場合は，requires 節は必要ありません。

contains 節は，ユニットファイルがコンパイルされてパッケージに結合されることを指定します。

たとえば次のコードでは，VCLDB30 パッケージが宣言されています。

package VCLDB30;

requires VCL30;

contains Db, Dbcgrids, Dbctrls, Dbgrids, Dbinpreq, Dblogdlg, Dbpwdlg, Dbtables;

end.


Rules for packages
Rules for packages1072011

Section topics	参照

パッケージは以下の規則にしたがわねばなりません。

Package names1072012

パッケージの名前はそのプロジェクトの中で重複しないものにします。パッケージに STATS と命名すると，パッケージエディタは STATS.DPK と呼ばれるソースファイルを生成します。コンパイラは，それぞれ TATS.DPL および STATS.DCP と呼ばれる実行可能なバイナリイメージを生成します。別のパッケージの requires 節でそのパッケージを参照したり，アプリケーションでそのパッケージを使うときには，STATS を使います。

The requires clause1072013

requires 節は，現在のパッケージで使われる，その他の外部のパッケージを一覧表示します。その機能は，Delphi ユニットファイルの uses 節に似ています。requires 節に表示された外部パッケージは，コンパイル時にアプリケーションに自動的にリンクされます。このアプリケーションは，現在のパッケージ，および外部パッケージに含まれるユニットの 1 つを両方とも使うアプリケーションです。

パッケージに含まれるユニットファイルが他のパッケージのユニットを参照する場合，パッケージの requires 節に他のパッケージを含めておく必要があります。他のパッケージが requires 節で省略されると，コンパイラは通常の方法で (DPL なしで) 参照ユニットを読み取ります。

メモ	ユーザーが作成するほとんどのパッケージには VCL 30 が必要です。VCL ユニットに依存する全パッケージ (SysUtils を含む)，または VCL30 を必要とする全パッケージは，requires 節に VCL30 をリストしていなければなりません。

Avoid circular package references1072014

パッケージは，requires 節に循環参照を含むことができません。

パッケージは，その独自の requires 節で自分を参照することはできません。

参照のチェーンは，そのチェーン内で参照なしで終了する必要があります。パッケージ A がパッケージ B を必要とするとき，パッケージ B はパッケージ A を参照できません。パッケージ A が B を必要とし，パッケージ B がパッケージ C を必要とするとき，パッケージ C はパッケージ A を参照できません。

Avoid duplicate package references1072015

パッケージの requires 節，または［実行時パッケージ］編集ボックスでのでの重複参照は，コンパイラにより無視されます。しかし明瞭で読みやすいプログラミングのためには，重複パッケージ参照を検出して，除去する必要があります。

The contains clause1072016

contains 節は，パッケージに結び付けるユニットファイルを指定します。独自のパッケージを記述している場合，ソースコードを .PAS ファイルに置いて contains 節にリストします。リストにはファイル名拡張子を含んではなりません。ユニットは，.DCU ファイルが見つからない場合，または .PAS ファイルが最後に構築されてから変更された場合にだけ再コンパイルされます。

Avoid redundant source code uses1072017

パッケージは，別のパッケージの contains 節またはユニットの uses 節にリストすることができません。

パッケージの contains 節に直接含まれるすべてのユニット，またはそれらの uses 節に間接的に含まれるすべてのユニットは，コンパイル時にパッケージに結び付けられます。パッケージに (直接または間接に) 含まれるユニットは，そのパッケージの requires 節で参照される他のパッケージに含むことはできません。

ユニットは，Delphi IDE も含め，同じアプリケーションで使われる複数のパッケージに (直接または間接に) 含むことができません。これは，VCL30 にユニットの 1 つを含むパッケージを作成した場合，IDE にパッケージをインストールできないことを意味します。既にパッケージ化したユニットファイルを別のパッケージで使うには，2 番目のパッケージの requires 節に最初のパッケージをリストします。


Compiling packages
Compiling packages1072018

Section topics	参照

IDE またはコマンドラインからパッケージをコンパイルできます。パッケージを含むプロジェクトを再構築すると，そのパッケージは必要な場合に暗黙的に再コンパイルされます。

パッケージを IDE から再コンパイルする方法は次のとおりです。

1.	［ファイル(F)｜開く(O)］を選択します。

2.	［ファイルの種類(T)］ドロップダウンリストから［Delphi パッケージソース (*.dpk)］を選択します。

3.	ダイアログで .DPK ファイルを選択します。

4.	パッケージエディタが開いたら，［コンパイル］スピードボタンをクリックします。

パッケージソースコードにはコンパイラ指令を挿入できます。詳細は，「コードにパッケージ独自のコンパイラ指令を挿入する」を参照してください。

コマンドラインからコンパイルする場合，パッケージ独自の新しいスイッチを使用できます。詳細は，「コマンドラインコンパイラの使い方」を参照してください。

Inserting package-specific compiler directives in code1072019

次の表は，ソースコードに挿入できるパッケージ独自のコンパイラ指令のリストです。

指令	目的
{$IMPLICITBUILD OFF}	パッケージが暗黙的に再コンパイルされるのを防ぐ。低レベル機能，構築から次の構築までめったに変更されない，あるいはそのソースコードが配布されないパッケージをコンパイルするとき，.DPK ファイルで使用する
{$G-} または  {IMPORTEDDATA OFF}	インポートされたデータ参照を作成不可にする。この指令は，メモリーアクセス効率を向上させるが，ユニットは他のパッケージの変数を参照できない
{$WEAKPACKAGEUNIT ON}	「弱い」パッケージユニット。以下の「$WEAKPACKAGEUNIT指令」の項参照
{$DENYPACKAGEUNIT ON}	ユニットがパッケージに置かれないようにする
{$DESIGNONLY ON}	IDE にインストールするためにパッケージをコンパイルする (.DPK ファイルに置く)
{$RUNONLY ON}	実行時だけパッケージをコンパイルする (.DPK ファイルに置く)
メモ	ソースコードに {$DENYPACKAGEUNIT ON} を含めると，ユニットファイルはパッケージに含まれません。{$G-} または {$IMPORTEDDATA OFF} を含めると，パッケージは，同じアプリケーションで他のパッケージと一緒に使用されません。{$DESIGNONLY ON} 指令でコンパイルされたパッケージは，IDE が必要とする例外コードを含むため，アプリケーションで通常は使用してはなりません。適切であれば，パッケージソースコードにその他のコンパイラ指令を含むこともできます。ここで解説していないコンパイラ指令については，「コンパイラ指令」を参照してください。

$WEAKPACKAGEUNIT directive1072020

$WEAKPACKAGEUNIT 指令は，.DCU ファイルのパッケージの .DCP および .DPL ファイルへの保管方法に影響します (コンパイラが生成するファイルについての詳細は，「正常なコンパイルで作成されるパッケージファイル」参照)。ユニットファイルに {$WEAKPACKAGEUNIT ON} が記述されていると，コンパイラは，可能であれば DPL にユニットを含めません。そして，他のアプリケーションやパッケージがそのユニットを必要としている場合は，ユニットのパッケージではないローカルコピーを作成します。この指令でコンパイルされたユニットは「弱いパッケージ」と呼ばれます。

たとえば，ユニットを1 つだけ (UNIT1) 含む PACK と呼ばれるパッケージを作成し，UNIT1 はこれ以上ユニットを含まず，RARE.DLL を呼び出すものとします。パッケージをコンパイルするとき，UNIT1.PAS に {$WEAKPACKAGEUNIT ON} を置いた場合，UNIT1 はPACK.DPL に含まれずに，PACK.DCP に含まれます。PACK を使う別のパッケージやアプリケーションにより UNIT1 が参照されると，UNIT1 は PACK.DCP からコピーされてプロジェクトに直接コンパイルされます。

ここで，2 番目のユニット UNIT2 を PACK に追加して，UNIT2 が UNIT1 を使うものとします。今度は，UNIT1.PAS で {$WEAKPACKAGEUNIT ON} により PACK をコンパイルしても，コンパイラは PACK.DPL に UNIT1 を含みます。しかし，UNIT1 を参照するその他のパッケージやアプリケーションは，PACK.DCP からの (パッケージではない) コピーを使います。

メモ	{$WEAKPACKAGEUNIT ON} 指令を含むユニットファイルには，グローバル変数，初期化部，終了処理部を含んではなりません。

$WEAKPACKAGEUNIT 指令は，DPL を他のDelphi プログラマに配布する開発者用の拡張機能です。ユーザーが DLL のめったに使わないものを配布するのを避け，同じ外部ライブラリに依存することのあるパッケージ間の衝突を除去するよう助けます。

たとえば，Delphi の PenWin ユニットは PENWIN.DLL を参照します。ほとんどのプロジェクトは PenWin を使いません。またほとんどのコンピュータには，PENWIN.DLL がインストールされていません。このため，PenWin ユニットは VCL30 では弱いパッケージです。PenWin と VCL30 を使うプロジェクトをコンパイルすると，PenWin は VCL30.DCP からコピーされてプロジェクトに直接結び付けられます。その実行の結果は PENWIN.DLL に静的にリンクされます。

PenWin が弱いパッケージではない場合，2 つの問題点が生じます。第 1 に，VCL30 自体が PENWIN.DLL に静的にリンクされるので，PENWIN.DLL がインストールされていないコンピュータにこれをロードできません。第 2 に，PenWin を含むパッケージを作成しようとすると，PenWin ユニットに VCL30 とパッケージの両方が含まれてしまうため，コンパイラエラーが生じます。したがって，弱いパッケージでなければ PenWin を VCL30 の標準配布に含むことはできません。

Using the command-line compiler1072021

コマンドラインからコンパイルすると，次の表に示すパッケージ独自のスイッチを使用できます。

スイッチ	目的
-$G-	インポートしたデータ参照の作成を不可にする。このスイッチを使うと，メモリーアクセス効率が向上するが，これでコンパイルしたパッケージは他のパッケージの変数を参照できない
-LEpath	パッケージの DPL ファイルを置くディレクトリを指定する
-LNpath	パッケージの DCP ファイルを置くディレクトリを指定する
-Z	後でパッケージが暗黙的に再コンパイルされるのを防ぐ。低レベル機能，構築から次の構築までめったに変更されない，あるいはそのソースコードが配布されないパッケージをコンパイルするとき使用する
メモ	-$G- スイッチを使うと，同じアプリケーションの中でパッケージが他のパッケージに使われるのを防ぐことがあります。適切であれば，パッケージをコンパイルするときその他のコマンドラインオプションを使うことがあります。ここで解説していないコンパイラ指令については，「コマンドラインコンパイラ」を参照してください。

Package files created by a successful compilation1072022

パッケージを作成するには，.DPK 拡張子を持つソースファイルをコンパイルします。.DPK ファイルの基準名は，コンパイラにより作成されるファイルの基準名になります。たとえば，TRAYPAK.DPK というパッケージソースファイルをコンパイルすると，コンパイラは TRAYPAK.DPL というパッケージを作成します。

以下の表は，パッケージの正常コンパイルにより作成されたファイルのリストです。

ファイル拡張子	内容
DCP	パッケージのヘッダーおよびパッケージのすべての DCU ファイルの連結を含むバイナリイメージ。各パッケージごとに 1 つの DCU ファイルが作成される。DCP の基準名は DPK ソースファイルの基準名である
DCU	パッケージに含まれるユニットファイルのバイナリイメージ。必要なとき，各ユニットファイルごとに 1 つの DCU ファイルが作成される
DPL	実行時パッケージ。このファイルは Delphi 独自の特別な機能を持つ，Windows DLL である。DPL の基準名は DPK ソースファイルの基準名になる


Distributing applications that use packages
Distributing applications that use packages1072023

Section topics	参照

実行時パッケージを使うアプリケーションを配布するときは，そのアプリケーションが呼び出すすべてのライブラリ (.DPL または .DLL) ファイルだけでなく，そのアプリケーションの .EXE ファイルをユーザーが持っていることを確認してください。ライブラリファイルが .EXE ファイルと異なるディレクトリにある場合，ユーザーのパスによりアクセスできなくてはなりません。また，ライブラリファイルを Windows\System ディレクトリに置く規則にしたがう必要があります。


Distributing packages to other developers
Distributing packages to other developers1072024

Section topics	参照

実行時または設計時パッケージを他の Delphi 開発者に配布する場合は，.DCP と .DPL ファイルの両方を渡すようにしてください。.DCU ファイルを含める場合もあります。


Package collection files
Package collection files1072025

Section topics	参照

パッケージコレクション (.DPC ファイル) は，他の開発者にパッケージを配布する簡単な方法です。各パッケージコレクションには，DPL や一緒に配布したい追加ファイルも含めて 1 つまたは複数のパッケージが含まれます。［インストール］ダイアログボックスでパッケージコレクションを選択すると，構成ファイルが自動的に .DPC コンテナから抽出されます。［インストール］ダイアログボックスでは，コレクションの全パッケージのインストールまたは選別したパッケージのインストールを選択できます。

パッケージコレクションを作成する手順は次のとおりです。

1.	［ツール(T)｜パッケージ］コレクションエディタを選択して，パッケージコレクションエディタを開きます。

2.	［パッケージの追加］スピードボタンをクリックして，［パッケージ選択］ダイアログから DPL を選択し，［開く］をクリックします。コレクションにもっと DPL を追加するには，［パッケージの追加］スピードボタンを再びクリックします。パッケージエディタの左側のツリー図に，追加した DPL が表示されます。パッケージを削除するには，そのパッケージを選択して［パッケージの削除］スピードボタンをクリックします。

3.	ツリー図の一番上にあるコレクションノードを選択します。パッケージコレクションエディタの右側に次の 2 つのフィールドが表示されます。

［オーサー/ベンダー名］編集ボックスには，ユーザーがパッケージをインストールするときにインストールダイアログに表示したいパッケージコレクションに関するオプションの情報を入力できます。

ディレクトリリストには，パッケージコレクションのファイルをインストールするデフォルトディレクトリをリストします。［追加］，［編集］，［削除］ボタンを使ってこのリストを編集します。たとえば，ソースコードをすべて同じディレクトリにコピーしたい場合，ディレクトリ名 Source を推奨パスと一緒に C:\MyPackage\Source と入力します。

4.	DPL のほかに，パッケージコレクションには，.DCP，.DCU，.PAS (ユニット) ファイル，文書，およびその他の配布したいファイルを含むことができます。補助ファイルは指定パッケージ (DPL) に関連付けられるファイルグループに含まれます。グループ内のファイルはその関連する DPL がインストールされるときだけインストールされます。補助ファイルをパッケージコレクションに含むには，ツリー図で DPL を選択して，［ファイルグループの追加］スピードボタンをクリックし，ファイルグループの名前を入力します。必要であれば，同じ方法でファイルグループをさらに追加します。ファイルグループを選択すると，パッケージコレクションエディタの右側に次の新規フィールドが表示されます。

［インストールディレクトリ］リストボックスで，このグループのファイルをインストールしたいディレクトリを選択します。ドロップダウンリストには，上記手順 3 でディレクトリリストに入力したディレクトリが含まれています。

このグループのファイルのインストールをオプションにしたい場合は，［オプショングループ］チェックボックスをチェックします。

インストールの一部として Delphi のグローバルなライブラリパスに［インストールディレクトリ］を追加するには，［ライブラリ検索パスの更新］チェックボックスにチェックを付けます。

［含まれるファイル］には，このグループに含みたいファイルをリストします。［追加］，［削除］，［自動］ボタンを使ってこのリストを編集します。［自動］ボタンを使うと，パッケージの contains 節にリストされる指定拡張子を持つファイルがすべて選択できます。パッケージコレクションエディタは，Delphi のグローバルライブラリパスを使ってこれらのファイルを検索します。

5.	コレクションの中のパッケージの requires 節にリストされるパッケージのインストールディレクトリを選択することができます。ツリー図で DPL を選択すると，パッケージコレクションエディタの右側に次の新規フィールドが表示されます。

［Required 実行］リストボックスでは，requires 節にリストされるパッケージの .DPL ファイルをインストールするディレクトリを選択します (ドロップダウンリストには，上記手順 3 でディレクトリリストに入力したディレクトリが含まれています)。パッケージコレクションエディタは，Delphi のグローバルライブラリパスを使ってこれらのファイルを検索し，Required 実行ファイルの下にリストします。

［Required ライブラリ］リストボックスでは，requires 節にリストされるパッケージの .DCP ファイルをインストールするディレクトリを選択します (ドロップダウンリストには，上記手順 3 でディレクトリリストに入力したディレクトリが含まれています)。パッケージコレクションエディタは，Delphi のグローバルライブラリパスを使ってこれらのファイルを検索し，Required ライブラリファイルの下にリストします。

6.	パッケージコレクションソースファイルを保存するには，［ファイル(F)｜上書き保存(S)］を選択します。パッケージコレクションソースファイルは，.PCE 拡張子を付けて保存しなければなりません。

7.	パッケージコレクションを構築するには，［コンパイル］スピードボタンをクリックします。パッケージコレクションエディタは，ソース (.PCE) ファイルと同じ名前の .DPC ファイルを生成します。ソースファイルを保存していないと，エディタはコンパイルする前にファイル名を要求します。

既存の .PCE ファイルを編集または再コンパイルするには，パッケージコレクションエディタで［ファイル(F)｜開く(O)］を選択します


See also1072026

コマンドラインコンパイラ

コンパイラ指令


Writing Object Pascal code
Writing Object Pascal code1073001

Section topics	参照

この章では，Object Pascal 言語の主な特徴を説明します。さらに，Object Pascal 言語を使ってイベントハンドラなどのアプリケーション各部のコードを記述する方法を説明します。この章と「Delphi オブジェクトを使ったプログラミング」を理解すれば，わかりやすく高性能な Delphi アプリケーションを開発できます。

この章では，読者にある程度のプログラミング経験があることを前提に話を進めます。しかし，専門家である必要はありません。一般的なプログラミング言語でプログラミングをした経験があれば十分です。Object Pascal はほかの言語と多くの点で共通です。なお，この章では Object Pascal で Delphi アプリケーションを開発するための一般的な方法を示していますが，Object Pascal 言語自体の詳しい解説は行いません。

Object Pascal の詳細については Delphi のオンラインヘルプの「言語定義」を参照してください。このヘルプトピックには，Object Pascal 言語のすべての構文を構文解析図で示してあります。ほかに，Pascal に関する一般書籍も参考になります。

Borland Pascal 言語に詳しい方は，この章はおおまかに目をとおすか，飛ばして「Delphi オブジェクトを使ったプログラミング」に進んでもかまいません。ただし，Object Pascal 言語に新しく追加された内容について，Delphi のオンラインヘルプを参照してください (ヘルプダイアログボックスのインデックスページを使用してください)。

この章では主に以下の内容について説明します。

読みやすいコードの書き方

代入文の書き方

識別子の宣言

定数の宣言

手続きと関数の呼び出し

コードの実行経路の制御

Object Pascal のブロック

スコープ

手続きと関数

新しいデータ型の定義

Object Pascal のユニット

この章を理解するには，Delphi プロジェクトの構造とイベントハンドラの作成方法についての予備知識が不可欠です。この予備知識を得るには第 2 部をお読みください。


Writing readable code
Writing readable code1073002

Section topics	参照

コンパイラがコンパイルして実行形式プログラムを生成するためのコードを記述するわけですが，人間が読みやすいコードを記述することも重要です。


Coding style
Coding style1073003

Section topics	参照

コードを書く前に留意する点があります。コンパイラにとっては，Object Pascal コードの空白，インデント，大文字と小文字の使い分け，改行方法は関係ないという点です。コンパイラの処理において重要なのは，コードの構文が正しいかどうかだけです。たとえば，次のようなコードでも問題なくコンパイルできます。

PROCEDURE

  TFORM1.

Button1CLICK(SENDER        :

       TOBJECT);begin

  Edit1.Color

:=

CLRED;END;

しかし，このイベントハンドラは次のように書き直した方が読みやすくなります。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Edit1.Color := clRed;

end;

コードのインデント，大文字と小文字の区別，改行は，読みやすいように必要に応じて使用します。


Commenting your code
Commenting your code1073004

Section topics	参照

コードには，任意の場所にコメントを挿入できます。

コードにコメントを挿入するには，

コメントのテキスト全体を中カッコ ({ }) で囲みます。

たとえば，次のように前述のイベントハンドラにコメントを追加します。

procedure TForm1.Button1Click(Sender: TObject);	{編集ボックスの色を変更}

begin

  Edit1.Color := clRed;

end;

複数の行に渡るコメントを書くこともできます。コンパイラは左中カッコ ({) から右中カッコ (}) までの内容をすべてコメントとみなします。

{このコメントは少し長いが

たいした意味はない。

コメントが複数の行に渡って

記述できることを示している}

procedure TForm1.Button1Click(Sender: TObject);	{編集ボックスの色を変更}

begin

  Edit1.Color := clRed;

end;

なお，コメントは必ず右中カッコで閉じてください。右中カッコを忘れると，コンパイラは残りのすべてのコードをコメントとみなしてしまいます。

コメントの行を追加するか，行の最後にコメントを追加したい場合は，スラッシュ 2 つ (//) が使えます。コンパイラは// からその行の最後までをすべてコメントとして扱います。

procedure TForm1.Button1Click(Sender: TObject);	// 編集ボックスの色を変更

begin

  Edit1.Color := clRed;

end;

コンパイラはコード内のすべてのコメントを無視して単なる空白とみなします。コードにコメントを追加する方法についての詳細は，Delphi オンラインヘルプの「コメント」を参照してください。

コメントの目的は，コードの意味を自分を含めた読み手に理解しやすくすることです。コードを記述した時点ではコードを理解していたつもりでも，後で見直したときに首をひねることもあります。


Writing assignment statements
Writing assignment statements1073005

Section topics	参照

イベントハンドラのコードを記述する作業で最も多いのは，プロパティや変数に新しい値を代入することです。プロパティの値はユーザーインターフェースの設計中にオブジェクトインスペクタで変更できます。しかし，アプリケーションの実行中に変更したい場合もあります。また，一部のプロパティは実行時にのみ変更できます。このようなプロパティには，オンラインヘルプのプロパティリファレンスで「実行時のみ」と注記しています。プロパティや変数を実行時に変更するには，代入文を記述します。

代入文は 2 つの部分で構成します。2 つの部分は Object Pascal の代入演算子 (:=) で分かれます。代入文の左側はプロパティ名や変数名で，右側はプロパティや変数に入れる新しい値です。代入文はセミコロン (;) で終了します。なお，すべての Object Pascal 文はセミコロンで終わります。

ボタンコントロールの OnClick イベントハンドラ内で使用する簡単な代入文を次に示します。この文では，Edit1 という編集ボックスコントロールの Color プロパティに値として clRed を代入します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Edit1.Color := clRed;

end;

Edit1 という編集ボックスコントロールと Button1 というボタンコントロールは，フォーム上にあるとします。ユーザーがフォームでボタンをクリックすると代入文が実行され，編集ボックスが赤色に変わります。

プロパティ名の前にピリオド (.) で区切ってコンポーネント名が書かれていることに注意してください。このようにプロパティ名だけでなくコンポーネント名も指定すると，どの Color プロパティを変更するかが明確になります。もしコンポーネント名を省略すると，ユーザーがボタンをクリックしたときにフォーム自体が赤色に変ってしまいます。詳細は「スコープ」を参照してください。


Assigning values to properties and variables
Assigning values to properties and variables1073006

Section topics	参照

値の代入先がプロパティでも変数でも代入方法は同じです。つまり，代入文の左側のプロパティまたは変数に，代入文の右側の値を代入します。代入する値を指定すると，プロパティまたは変数には指定した値のコピーが入ります。代入する値としては，定数，リテラル値，変数，ほかのプロパティ値があります。次に例を示します。

var

  Name: string;

  Number: Integer;

begin

  Name := Edit1.Text;	{変数にプロパティ値を代入する}

  Number := 15;	{変数にリテラル値を代入する}

  Edit2.Text := 'Welcome to Delphi, ' + Name;

{文字列定数と文字列変数で構成された文字列をプロパティに代入する}

end;

前のトピックのコード例では，ボタンクリックに応答してコンポーネント (この例では編集ボックス) の色を設定または変更するために，代入文を使用しています。次は，編集ボックスの色を変更するのにカラーグリッドを使用します。つまり，カラーグリッドでユーザーが色をクリックすると編集ボックスの色が変わるようにします。

次のフォームはカラーグリッドの OnClick イベントに対応するイベントハンドラの作成例です。

procedure TForm1.ColorGrid1Click(Sender: TObject);

begin

  Edit1.Color := ColorGrid1.ForegroundColor;

end;

プロパティ値を別のプロパティに代入する例

アプリケーションを実行し，カラーグリッドで色をクリックすると，代入文で Edit1.Color プロパティに ColorGrid1.Foreground プロパティの値を代入しているので，編集ボックスの色はカラーグリッドでユーザーがクリックした色に変わります。

変数やプロパティには，プロパティ，変数，定数，リテラルの値を代入できます。ただし，代入する値は代入先の変数やプロパティと同じ型であるか，または代入互換性を持つ型であることが条件です。型や代入互換性についての詳細は「型と代入互換性」を参照してください。

プロパティや変数の型は，プロパティや変数で使用できる値の範囲と，プロパティや変数に対するコードで何を操作できるかを定義します。先の例では，Color (編集ボックスのプロパティ) も ForegroundColor (カラーグリッドのプロパティ) も同じ TColor 型です。

プロパティの型を調べるには，オンラインヘルプでプロパティを検索するか，オブジェクトインスペクタでプロパティを選択して〔F1〕を押します。型はプロパティ宣言の最後の要素です。たとえば，次の Color プロパティ宣言は Color を TColor 型として宣言します。

property Color: TColor;

メモ	すべてのプロパティに新しい値を代入できるわけではありません。一部のプロパティは読み出し専用です。つまり，プロパティの値を参照することはできますが，これをアプリケーションで変更することはできません。Delphi オンラインヘルプでは，読み出し専用プロパティにはそのことを明記しています。


Declaring identifiers
Declaring identifiers1073007

Section topics	参照

識別子とは，Delphi アプリケーションの構成単位である変数，型，手続き，関数，メソッドなどに付けた名前です。Object Pascal の規則では，コードで使用する識別子は最初に宣言します。

以前にコンパイラ言語を使ったことがない場合は，識別子を宣言してから使用することに違和感があるかもしれません。しかし，これはすべてのコンパイラ言語に共通することです。コンパイラに識別子の情報を事前に与えないと，コンパイラは識別子を使用する実行コードを作成できません。

コンパイラは与えられた情報に基づいてコードをチェックし，変数やプロパティに代入した値が正しい型になっているかどうか確認します。正しくない型を発見すると構文エラーメッセージを表示し，開発者にエラーの位置などを知らせます。非コンパイラ言語では，誤った型の値を代入するという一般的なプログラミングエラーを防げません。その点，Object Pascal は型チェックの厳しい言語として知られています。

また，コンパイラ言語である Object Pascal で構築した Delphi アプリケーションは，インタープリタ言語で構築したアプリケーションよりも実行速度がはるかに優ります。結局，識別子を使用前に宣言することは，プログラミングエラーを減らしてコードの効率を上げることにつながります。


Declaring variables
Declaring variables1073008

Section topics	参照

変数はメモリアドレスを表すコード内の名前であり，変数の値はコードの実行中に変化します。変数を使用するには，次の 2 つのステップをとおしてあらかじめ宣言します。

1.	変数の命名

2.	変数の型の指定

Naming a variable1073009

変数を宣言するには，最初に変数に名前を付けます。このとき，変数の機能を具体的に示すような名前にすると，コードがわかりやすくなります。たとえば，X，Y，Z などとせずに Day，Name，Total のようにします。

このほか，変数を含むすべての識別子に適用される命名規則を以下に示します。

識別子の長さは 63 文字以内とする
識別子の長さが 63 文字を超えるとコンパイラは超えた部分の文字を無視します。

識別子の先頭には英文字または下線 (_) を使う

先頭文字の後には英数文字または下線を使う

ほかの記号 ($，%，* など) を識別子で使うことはできない
たとえば，Do@Noon や Gross%Return という識別子は構文エラーになります。

ひらがな，カタカナ，漢字を使うことはできない

Object Pascal の予約語は識別子の名前として使用できない
予約語はコンパイラが特別な意味で使用しています。予約語を識別子に使用するとエラーメッセージが生成されます。Object Pascal 予約語のリストはオンラインヘルプの「予約語」を参照してください。なお，Delphi のマニュアル内のサンプルコードではすべての予約語を太字で表記します。

Object Pascal 言語の定義済みの識別子を識別子の名前にしない
たとえば，Boolean や Integer は定義済みのデータ型です (定義済みのデータ型についての詳細は「データ型」を参照)。変数名にこれらの定義済みの語を使用してもエラーメッセージは生成されません。しかし，かわりに Boolean 型や Integer 型をコードで使用できなくなります。

Giving a variable a type1073010

変数を宣言するときは，その型も指定します。型は，変数が取り得る値の範囲を定義します。

一般に変数は使用する場所で宣言します。たとえば，変数をイベントハンドラで使用する場合はイベントハンドラ内で宣言します。変数宣言の場所についての詳細は「Object Pascal のブロック」と「スコープ」を参照してください。

変数宣言部の先頭には予約語 var を記述します。宣言自体は 2 つの部分から構成されます。左側の部分は新しい変数の名前を示し，右側の部分は変数の型を宣言します。両者の間はコロン (:) で区切ります。Value，Sum，Line という 3 つの変数を宣言する例を次に示します。

var

  Value: Integer;

  Sum: Integer;

  Line: string;

Value と Sum はどちらも Integer 型です。同じ型に属する 2 つの変数はカンマ (,) で区切り，次のように宣言することもできます。

var

  Value, Sum: Integer;

  Line: string;

次の例では，フォームに Edit1 という編集ボックスと AddButton というボタンがあるとします。3 つの変数 (X，Y，Sum) は Integer 型として宣言します。ユーザーが AddButton をクリックすると，2 つの変数 X と Y に Integer 型の値を代入して加算します。そして，加算した合計値 Sum を編集ボックスに表示します。

procedure TForm1.AddButtonClick(Sender: TObject);

var

  X, Y, Sum: Integer;

begin

  X := 100;

  Y := 10;

  Sum := X + Y;

  Edit1.Text := IntToStr(Sum);

end;

次の行では変数に式の値を代入します。

Sum := X + Y;

式とは，通常 2 つの識別子を演算子で関係付けたものを指します。なお，式についての詳細はオンラインヘルプの「式」を参照してください。編集ボックスの Text プロパティは string 型であり，Sum 変数は Integer 型です。したがって次の行は正しくなく，これをコンパイルしようとすると型の不一致エラーになります。

Edit1.Text := Sum;

このイベントハンドラの例では，最終行でこのようには記述していません。かわりに，Delphi ランタイムライブラリの IntToStr 関数を使って Sum 値をテキスト文字列に変換し，このテキスト文字列を Edit1.Text プロパティに代入しています。

次の例は，Sum に値を代入しないで同じ処理を行う方法を示しています。

procedure TForm1.AddButtonClick(Sender: TObject);

var

  X, Y: Integer;

begin

  X := 100;

  Y := 10;

  Edit1.Text := IntToStr(X + Y);

end;

コードで関数を使う方法は「関数の呼び出し」で詳しく説明しますが，関数は特定の型の値を返すこと，そしてこの値は変数やプロパティに代入できることを，覚えておいてください。

Data types1073011

Object Pascal ではいくつかのデータ型が言語に組み込まれています。これらの定義済みデータ型の変数は自由に作成できます。表 6.1 に定義済みのデータ型を示します。

分類	データ型	説明
整数	ShortInt	-128～127 の小数部なしの数値。1 バイトのメモリを使用
	SmallInt	-32768～32767 の小数部なしの数値。2 バイトのメモリを使用
	LongInt	-2147483648～2147483647 の小数部なしの数値。4 バイトのメモリを使用
	Integer	実装に依存するデータ型。このバージョンの Object Pascal では Integer は LongInt と同じ
	Byte	0～255 の小数部なしの数値。1 バイトのメモリを使用
整数	Word	0～65535 の小数部なしの数値。2 バイトのメモリを使用
	Cardinal	実装に依存する型。このバージョンの Object Pascal では，Cardinal は負でない値のみ使用できる Integer と同じ
実数	Single	有効桁数 7～8 桁の小数部を含む数字。4 バイトのメモリを使用。(各実数型の値の範囲についてはオンラインヘルプの「実数型」を参照)
	Double	有効桁数 15～16 桁の小数部を含む数字。8 バイトのメモリを使用
	Extended	有効桁数 19～20 桁の小数部を含む数字。10 バイトのメモリを使用
	Comp	有効桁数 19～20 桁の整数。8 バイトのメモリを使用。8087/80287 オプション {N+} がオンのときだけ使用可能
	Currency	4 桁の小数部を持つ高精度の実数
	Real	有効桁数 11～12 桁の小数部を含む数字。6 バイトのメモリを使用。Real は Borland Pascal の旧リリースとの下位互換用。それ以外は Double または Extended を使用のこと
論理値	Boolean	True または False の値を含む。1 バイトのメモリを使用
文字	AnsiChar	Ansi 文字
	WideChar	Unicode 文字
	Char	実装に依存する型。このバージョンの Object Pascal では Char は AnsiChar と同じ
文字列	ShortString	255 文字以内の長さの文字列
	AnsiString	実質的に長さに制限のない動的文字列
	string	$H コンパイラ指令に依存する型。デフォルトでは string は AnsiString と同じ
	WideString	AnsiString と同じだが，内部表現に Unicode を使用
	PWideChar	ヌルで終わる Unicode 文字列へのポインタ
ポインタ	Pointer	型なしポインタ。特定の型を指さないポインタ
PChar	PChar	ヌルで終わる文字列へのポインタ
バリアント	Variant	異なる複数の型として値を保持できるデータ型。値は必要に応じてほかの型に変換される
定義済みデータ型とは別に独自のデータ型も定義できます。通常の Delphi アプリケーションは定義済みのデータ型で十分です。しかし，この章ではユーザー定義のデータ型もすでに紹介しています。Color プロパティは TColor 型ですが，このデータ型は Object Pascal の定義済みデータ型ではなく，Delphi ランタイムライブラリで定義している型です。定義済みデータ型についての詳細はオンラインヘルプの「型宣言」を参照してください。独自のデータ型を定義する方法についての詳細は「新しいデータ型の定義」を参照してください。

Type and assignment compatibility1073012

表「Object Pascal の定義済みデータ型」には，整数の分類に属するデータ型として 5 つ，実数の分類に属するデータ型として 5 つの型があります。同じ分類内の型は互いに互換性があります。つまり，あるデータ型の値は，同じ分類内の別のデータ型の変数やプロパティに代入できます。ただし，代入する値は代入先の変数やプロパティの取り得る値の範囲内でなければなりません。

たとえば，Shortint 型の変数には Integer 型の変数の値 7 を代入できます。Shortint 型の値の範囲は -128～127 だからです。しかし，Integer 変数の値を 300 にすると Shortint 型の値の範囲外になるので，Shortint 型には代入できません。範囲チェックが有効の場合にあえてこの代入を行うと，実行時に範囲エラーが発生します。範囲チェックのオン/オフを設定するには，［プロジェクト(P)｜オプション(O)］を選択し，［コンパイラ］ページの［範囲チェック(R)］を設定します。範囲チェックがオフの場合はコードを実行できますが，実際に代入される値は予想と異なるはずです。

異なる分類に属する変数やプロパティに値を代入できる場合もあります。ただし一般的に，値の範囲の小さいデータ型の値を値の範囲の大きいデータ型へ代入する場合に限られます。たとえば，Double 型のプロパティには Integer 型の値を代入できます。Double 型は小数点値を含むので値 10 を代入すると値 10.0 として受け取ります。しかし，Integer 型の変数やプロパティには Double 型の値を代入できません。Integer 型には小数部がないためです。

データ型の互換性を確認するには，Delphi オンラインヘルプの「型の互換性」と「代入の互換性」を参照し，型互換性と代入互換性の詳しい規則を調べてください。


Declaring constants
Declaring constants1073013

Section topics	参照

変数の値がアプリケーションの実行中に変化するのに対して，定数の値は不変です。定数の値は宣言時に指定します。

変数を変数宣言で宣言するように，定数は定数宣言で宣言します。定数宣言は予約語の const で始めます。3 つの定数を宣言する例を次に示します。

const

  Pi = 3.14159;

  Answer = 342;

  ProductName = 'Delphi';

Pi，Answer，ProductName は定数の値を入れる定数名です。定数の実際の値はそれぞれ 3.14159，342，'Delphi' です。それぞれの値はアプリケーションの実行中に変化しません。定数の名前は「変数の宣言」で述べた変数を含む識別子の命名規則に従って付けます。

変数と同じように定数にも型があります。ただし変数とは異なり，定数は定数宣言部で宣言した値に対応した型になります。たとえば，定数 Pi の値 3.14159 は実数なので Real 型になり，定数 Answer の値 342 は整数なので Integer 型になり，定数 ProductName の値 'Delphi' はテキスト文字列なので string 型になります。

なお，定数宣言で使用する等号 (=) は代入文で使用する代入演算子 (:=) とは異なります。定数宣言の等号は，宣言の左辺と右辺が等しい値であることを示します。

Object Pascal コードでは等号の使い方を間違えることがよくあります。代入演算子のかわりに間違えて等号を使用すると，コンパイラは，文の左側が定数であるか，または 2 つの値を比較していると判断します。これ以外の文脈で等号を間違えて使用した場合は構文エラーメッセージが表示されます。

逆に，定数宣言で等号のかわりに間違えて代入演算子を使用した場合も構文エラーになります。コンパイラは等号を要求するメッセージを表示します。


Calling procedures and functions
Calling procedures and functions1073014

Section topics	参照

手続きと関数は，特定の処理を行うコードの部分です。ほかの言語ではサブルーチンとも呼ばれます。Delphi のランタイムライブラリには以下の内容が含まれます。

Delphi の System ユニット，SysUtils ユニット，Math ユニットの手続きと関数

これらのルーチンやそのデータ型と一緒に使う変数と定数

エラーを知らせるための例外オブジェクト

手続きと関数のコードは記述済みなので新しくコードを書く必要はなく，また，コードの内容を理解する必要もありません。手続きと関数の目的だけを理解していれば十分です。

コンポーネントやコントロールなどのオブジェクト内で宣言した手続きや関数は，メソッドと呼ばれます。オブジェクトは一種のデータ型であり，「Delphi オブジェクトを使ったプログラミング」で詳しく解説します。


Calling procedures
Calling procedures1073015

Section topics	参照

すでにお気付きかもしれませんが，すべてのイベントハンドラは予約語 procedure で始まります。すべてのイベントハンドラは手続き (プロシージャ) です。つまり，アプリケーションの処理を管理しやすい単位に分けたサブルーチンです。各イベントハンドラには，対応するイベントの発生時に実行するコードだけを入れます。

既存の手続きを使うには，手続きの名前を文としてコード内に記述します。
これを「手続きの呼び出し」といいます。

たとえば，メモコンポーネントには CutToClipboard メソッドがあります。このメソッドはユーザーがメモコンポーネント内で選択したテキストを削除し，これをクリップボードオブジェクトに格納します。この機能はメソッドに組み込まれているので，このメソッドを使うにはメソッドの目的と使い方を理解するだけで十分です。Memo1 というメモコントロールの CutToClipboard メソッドを呼び出す方法は，次のとおりです。

Memo1.CutToClipboard;

ここで，コントロールの名前 Memo1 をメソッド呼び出しの一部として使用しています。コントロールの名前を指定することによって，どの CutToClipboard メソッドを呼び出すのか明確になります。コントロールの名前とメソッド呼び出しの間はピリオド (.) で区切ります。メソッド呼び出しで，コントロール，コンポーネント，オブジェクトの名前を忘れると次のような構文エラーが表示されます。

未定義の識別子  (Unknown identifier)

アプリケーションで Memo1.CutToClipboard を呼び出すと，CutToClipboard メソッド内のコードが実行され，ユーザーの選択したテキストが切り取られてクリップボードオブジェクトに入ります。

Cut, Copy, Paste, and Clear All: An example1073016

Delphi ライブラリの手続きを呼び出す例を示します。

各ボタンに対して次にような OnClick イベントハンドラのコードを記述します。

procedure TForm1.CutClick(Sender: TObject);

begin

  Memo1.CutToClipboard;

end;

procedure TForm1.CopyClick(Sender: TObject);

begin

  Memo1.CopyToClipboard;

end;

procedure TForm1.PasteClick(Sender: TObject);

begin

  Memo1.PasteFromClipboard;

end;

procedure TForm1.ClearAllClick(Sender: TObject);

begin

  Memo1.Clear;

end;

アプリケーションを実行すると，メモコントロールにテキストを入力し，テキストの切り取り，コピー，貼り付け，クリアを自由に行うことができます。［Cut］ボタンをクリックするとメモの CutToClipboard メソッドが実行されます。［Copy］ボタンをクリックするとメモの CutToClipboard メソッドが実行されます。そのほかも同様です。

Calling procedures with parameters1073017

多くの手続きではパラメータを指定する必要があります。手続きを呼び出す文は，手続きのコードを実行するときにパラメータに渡された値を使用します。パラメータは呼び出された手続き内で宣言された変数と同じように扱われます。手続き呼び出しでは，パラメータを丸カッコの中に入れます。たとえば，LoadFromFile メソッドは TStrings オブジェクトの中で次のように宣言されています。

procedure LoadFromFile(const FileName: string);

FileName は，このメソッドの唯一のパラメータであり，string 型に属します。LoadFromFile メソッドを呼び出すとき，読み込むファイルを指定するには FileName パラメータに文字列を指定します。次のコードでは MYFILE.TXT ファイルをメモコントロールの各行へ読み出します。

Memo1.Lines.LoadFromFile('MYFILE.TXT');

文字列の値を直接指定せずに，string 型の変数または式を指定することもできます。

var

  Name: string;

begin

  Name := 'MYFILE.TXT';

  Memo1.Lines.LoadFromFile(Name);

end;

さらに，string 型のプロパティの値も指定できます。次の例では Open ダイアログボックスの Execute メソッドを最初に呼び出し，ダイアログボックスを表示します。ダイアログボックスでファイル名を選択すると，このファイル名は LoadFromFile メソッドのパラメータとして渡されます。

begin

  OpenDialog1.Execute;

  Memo1.Lines.LoadFromFile(OpenDialog1.FileName);

{ユーザーがパラメータを指定する}

end;

Open ダイアログボックス (TOpenDialog コンポーネント) と FileName プロパティについての詳細は，Delphi オンラインヘルプを参照してください。

また，パラメータについての詳細は「パラメータの受け渡し」を参照してください。


Calling functions
Calling functions1073018

Section topics	参照

手続きと同じように関数も特定の処理を行うコードを実行します。また，手続きと同じようにオブジェクト，コンポーネント，コントロールの中で宣言する関数をメソッドと呼びます。

ただし，関数は実行後に値を返すという点で手続きと異なります。手続きは値を返しません。関数から返された戻り値は，以下のどちらかの用途に使えます。

戻り値をプロパティまたは変数に代入する

戻り値によってコードの実行経路を決定する

Assigning a function's returned value1073019

次のコード例は「変数の型の指定」に示したものと同じです。

procedure TForm1.AddButtonClick(Sender: TObject);

var

  X, Y, Sum: Integer;

begin

  X := 100;

  Y := 10;

  Sum := X + Y;

  Edit1.Text := IntToStr(Sum);

end;

この例では IntToStr 関数を使用しています。

Edit1.Text := IntToStr(Sum);

IntToStr では Longint 型の整数値を string 型の値に変換します。次に Delphi ランタイムライブラリの IntToStr 関数の宣言を示します。

function IntToStr(Value: Longint): string;

すべての関数宣言は予約語 function で始めます。関数宣言の最後のコロン (:) に続く語は戻り値のデータ型を示します。つまり，IntToStr 関数は string 型の値を返すことがわかります。

IntToStr 関数のコードを実行すると，代入文は Edit1 という編集ボックスの Text プロパティに文字列の戻り値を代入します。

Value は IntToStr 関数の唯一のパラメータであり，整数に属する Longint 型のデータです。IntToStr の Value パラメータとしては以下のものが指定できます。

整数値

IntToStr(3)

整数の変数またはプロパティ

IntToStr(Sum)

整数値として評価される式 (次の例では X と Y を整数値とする)

IntToStr(X+Y)

To call a function,

関数を呼び出すには，戻り値と対応する変数またはプロパティに戻り値を代入します。

Edit1.Text := IntToStr(Sum);

Using functions that return a Boolean value to branch code1073020

関数には論理値を返すものがあります。論理値とは True (真) または False (偽) のどちらかです。この種の関数を使うと，戻り値に応じてコードの実行経路をさまざまな処理やルーチンへ分岐させることができます。

たとえば，次のフォームでは 1 つのカラーダイアログボックスと 1 つのボタンを追加し，OnClick イベントに対して次のイベントハンドラを作成します。

procedure TForm1.ChangeColorClick(Sender: TObject);

begin

if ColorDialog1.Execute then	{ユーザーが［OK］ボタンをクリックした場合}

   Form1.Color := ColorDialog1.Color

else

   Form1.Color := clRed;

end;

Execute メソッドの使用例を示すフォーム

イベントハンドラは論理値を返す Execute メソッドを使用します。ユーザーは，ダイアログボックスで色を指定して［OK］を選択するか，［キャンセル］を選択して色を指定せずにダイアログボックスを終了するかのどちらかを行えます。ColorDialog1.Execute メソッドは［OK］を選択すると True を返し，［キャンセル］を選択すると False を返します。ColorDialog1.Execute が True を返すとフォームは指定した色に変わります。つまり，Form1.Color に ColorDialog1.Color の値が代入されます。このメソッドが False を返すとフォームは赤色になります。

Execute メソッドを次のように記述してもコンパイラの解釈は同じです。

if ColorDialog.Execute = True then ...


Controlling the flow of code execution
Controlling the flow of code execution1073021

Section topics	参照

Object Pascal にはコード実行経路を制御する文がいくつかあります。以下の分岐文とループ文です。

分岐文

if 文

case 文

ループ文

repeat 文

while 文

for 文


The if statement
The if statement1073022

Section topics	参照

Object Pascal の if 文は式を評価し，この評価の結果に基づいてコードの流れを決定します。条件が True であるか False であるかによって，コードの流れを別の方向へ分岐させます。if 文の構文については Delphi オンラインヘルプで予約語 if を参照してください。

簡単な if 文の使用例を示します。

ボタンの OKClick イベントハンドラを作成します。

procedure TForm1.OKClick(Sender: TObject);

begin

  if Edit1.Text = 'Saturday' then

    Label2.Caption := 'Why are you working today?';

end;

このイベントハンドラでは，等号演算子 (=) を関係演算子として使用しています。この演算子で定数 Saturday の値と Edit1.Text プロパティの値を比較します。

このハンドラに示した if 文は最も単純な部類に入ります。if 文は予約語 if で始め，True または False の論理値を返す式を続けます。式が True であれば予約語 then に続くコードが実行されます。つまり，編集ボックスコントロールに Saturday と入力してフォームで［OK］をクリックすると，2 番目のラベルにメッセージ Why are you working today ? が表示されます。

Using an else part in an if statement1073023

この単純なアプリケーションのロジックには欠陥があります。編集ボックスに Saturday と入力して［OK］ボタンをクリックした後で，Monday と入力して［OK］ボタンをクリックするとどうなるでしょうか。実は，Saturday 用のメッセージは 2 番目のラベルに残ってしまいます。これを解決するには，if 文に else 部を追加し，編集ボックスに Saturday 以外の文字列が入力された場合の処理を指定します。

たとえば，イベントハンドラを次のように変更します。

procedure TForm1.OKClick(Sender: TObject);

begin

  if Edit1.Text = 'Saturday' then

    Label2.Caption := 'Why are you working today?'

  else

    Label2.Caption := '';

end;

この if 文には予約語 else が含まれています。else に続く文は，次のテスト条件が False のときに実行されます。

Edit1.Text = 'Saturday'

else 部の文は Caption プロパティをクリアします。� � (単引用符 2 つ) は空の文字列を示します。

メモ	この例では，else 部の最後までセミコロン (;) を使用していません。else 部の前にセミコロン (;) を挿入するとエラーになります。

Writing multiple statements within an if statement1073024

if 文のテスト条件が True のときに複数の処理を行うには，begin..end ブロック内に複数の文を記述します。次のイベントハンドラはメッセージを表示し，同時にフォームを黄色に変更するように拡張したものです。

procedure TForm1.OKClick(Sender: TObject);

begin

  if Edit1.Text = 'Saturday' then

  begin

    Label2.Caption := 'Why are you working today?';

    Form1.Color := clYellow;

  end

  else

    Label2.Caption := '';

end;

begin..end ブロック内の各文はセミコロン (;) で終わっています。しかし，else 部の前にはセミコロン (;) を付けてはいけないことを覚えておく必要があります。上の例では if 文の if 部に複数の文を記述した後で end を使用していますが，この end にはセミコロン (;) を付けていないことに注目してください。

メモ	複数の文は任意の場所に記述できます。ただし，複数の文の前には必ず begin を使用し，最後には end を使います。このような複数の文を複合文と呼びます。複合文についての詳細は，Delphi オンラインヘルプを参照してください。

Nesting if statements1073025

アプリケーションのロジックで必要であれば，if 文の中で if 文を使用できます。たとえば，次に示す OKClick ハンドラでは 3 つの条件をテストしています。

procedure TForm1.OKClick(Sender: TObject);

begin

  if Edit1.Text = 'Saturday' then

    Label2.Caption := 'Why are you working today?'

  else

    if Edit1.Text = 'Sunday' then

      Label2.Caption := 'You should be resting'

    else

      if Edit1.Text = 'Monday' then

        Label2.Caption := 'Welcome to a new work week!'

      else

          Label2.Caption := '';

end;

最初に条件が一致した部分が実行され，それ以降の条件はテストされません。つまり，編集ボックスに Saturday と入力するとラベルには Saturday 用のメッセージが表示され，それ以降の if 文のテストは無視されます。

メモ	最後の else 部までセミコロン (;) は使用しません。ネストした if 文を書くときは一貫した見やすいインデントを行い，アプリケーション実行時の if 文のロジックとコードの流れを簡単に理解できるようにします。ただし，このインデントはプログラムの流れには影響を与えないことを忘れないでください。if 文がわかりにくい場合は，流れを明瞭にするために次の例のように begin..end ブロックを使います。

if Edit1.Text = 'Saturday' then

begin

  Label2.Caption := 'Why are you working today?';

end

else

begin

  if Edit1.Text = 'Sunday' then

  begin

    Label2.Caption := 'You should be resting';

  end

  else

  begin

    if Edit1.Text = 'Monday' then

    begin

      Label2.Caption := 'Welcome to a new work week!';

    end

    else

    begin

      Label2.Caption := '';

    end

  end

end

else 部を含む if 文を else 部を含まない if 文内にネストすることもできます。ネストした if 文は次のような構造になります。

if ConditionA = True then

  if Condition B = True then

    DoThis

  else

    DoThat;

このような構造にした場合，コンパイラは else 部を最も内側の if 文に属するものとみなします。ConditionB の値とは関係なしに，ConditionA が False のときに必ず DoThat を呼び出したい場合は，コードを次のように記述します。

if ConditionA = True then

  begin

    if ConditionB = True then

      DoThis

  end

else

  DoThat;

この場合，予約語 begin と end があるため，else 部は最初の if 文に関連付けられます。


The case statement
The case statement1073026

Section topics	参照

アプリケーションの実行を適切な行に分岐させるために，case 文を使うこともできます。多くの if 文を続けて使用するような場合，評価対象の変数またはプロパティが順序型であれば，if 文のかわりに case 文を使用すると便利です。一般に case 文のロジックは複雑にネストした if 文よりも読みやすく，コードの実行速度も速くなります。

case 文の構文についての詳細は，オンラインヘルプで予約語 case を参照してください。

次に case 文を使用するフォームの例を示します。

ボタンの OKClick イベントにイベントハンドラを作成します。

procedure TForm1.OKClick(Sender: TObject);

var

  Number: Integer;

begin

  Number := StrToInt(Edit1.Text);

  case Number of

    1, 3, 5, 7, 9: Label2.Caption := 'Odd digit';

    0, 2, 4, 6, 8: Label2.Caption := 'Even digit';

    10..100: Label2.Caption := 'Between 10 and 100';

  else

    Label2.Caption := 'Greater than 100 or negative';

  end;

end;

アプリケーションを実行し，数値を入力して［OK］を選択すると，数値を表す文字列は整数に変換されて変数 Number に代入されます。case 文では，Number の値によって case 文内のどの文を実行するかが決まります。コード中の次に示す行は，Number の値が 1，3，5，7，9 のいずれかのときに使われ，コロン (:) の後に続く文が実行され，Label2.Caption に文字列 'Odd digit' が代入されます。

1, 3, 5, 7, 9: Label2.Caption := 'Odd digit';

if 文と同じように，case 文にも else 部を記述できます。case 文は予約語 end で終了させます。

メモ	case 文の実行部 (コロン (:) の後に続く部分) に複数の文を含める場合は，複数の文の前後に予約語 begin と end を使います。次に例を示します。

case Number of

  1, 3, 5, 7, 9:

  begin

    Label2.Caption := 'Odd digit';

    Form1.Color := clBlue;

  end;

  2, 4, 6, 8: Label2.Caption := 'Even digit';

  ...


Writing loops
Writing loops1073027

Section topics	参照

Object Pascal にはコードのブロックを繰り返して実行する文が 3 つあります。

repeat 文

while 文

for 文

The repeat statement1073028

repeat 文は，特定の条件が True になるまで文を繰り返します。repeat 文は予約語 repeat で始まり，予約語 until で終わります。until の後に評価する条件を記述します。この条件は常に論理式となります。

repeat 文の構文についての詳細は，オンラインヘルプで予約語 repeat を参照してください。

次に，repeat 文を使用するフォームの例を示します。

ボタンのイベントハンドラを作成します。

procedure TForm1.RepeatButtonClick(Sender: TObject);

var

  I: Integer;

begin

  I := 0;

  repeat

    I := I + 1;

    Writeln(I);

  until I = 10;

end;

アプリケーションを実行し，［Repeat］ボタンをクリックすると，Form1 ウィンドウの脇にコンソールウィンドウが現れ，1～10 の数字が書き込まれます。論理式 I=10 は repeat..until ブロックの最後に評価されます。そのため，repeat..until ブロック内の文は，少なくとも 1 回は必ず実行されます。

repeat 文についての詳細は，Delphi オンラインヘルプを参照してください。

The while statement1073029

repeat 文がループの最後に条件を評価するのに対して，while 文はループの最初に条件を評価します。while 文は予約語 while で始め，この後に評価する条件を記述します。条件は常に論理式となります。条件が一致して式が True になると，while 文の残りのコードが実行され，その後で再び条件の式が評価されます。式が False になると while 文の実行は終了し，while ループ後の処理が続行されます。

次に示す while ループの例では，repeat ループの例と同じフォームを使います。作成するフォームは次のとおりです。

ボタンのイベントハンドラを作成します。

procedure TForm1.WhileButtonClick(Sender: TObject);

var

  J: Integer;

begin

  J := 0;

  while J < 10 do

  begin

    J := J + 1;

    Writeln(J:50);

  end;

end;

アプリケーションを実行して，［While］ボタンをクリックすると，次の論理式が最初に評価されます。

J < 10

この式が True であれば，while 文は残りのコードを実行してから式の評価を繰り返します。式が False であれば，while 文は実行を終了します。

［While］ボタンをクリックすると，1～10 までの数字が再び表示されます。今度の表示は，コンソールウィンドウの左端から 50 文字分離れた場所になります。

RepeatButtonClick ハンドラの文 I:=0 を I:=10 に変更します。さらに，WhileButtonClick ハンドラの文 J:=0 を J:=10 に変更します。最後に，アプリケーションを実行しボタンのどれかをクリックします。

［Repeat］ボタンをクリックすると，すでに I=10 になっていますが，repeat ループ内の文は実行されます。この論理式は repeat 文の最後に評価されるからです。I = 10 が再び成立するまで，ループの実行は続きます。

［While］ボタンをクリックしても，while ループ内の文は 1 回も実行されません。すでに J は 10 になっているので論理式は False になり，while 文がただちに終了するためです。

while 文についての詳細は，Delphi オンラインヘルプを参照してください。

The for statement1073030

これまで repeat 文と while 文の 2 種類のループを解説しました。repeat 文の実行は条件が True になるまで (until) 続きます。while 文の実行は条件が True である間 (while) 続きます。Object Pascal の 3 番目のループとして，for 文があります。for ループ内のコードは特定の回数だけ実行されます。

for 文を実行する回数は制御変数の値で指定します。制御変数はカウンタとして機能します。for ループごとに，それぞれの制御変数が必要です。制御変数は通常，整数型ですが，論理型，文字型，列挙型，部分範囲型を指定することもできます。

for 文は例で理解するのが最も簡単です。次に示すコードでは，数値 1～5 をそれぞれ別の行に表示します。X が制御変数です。

var

  X: Integer;

for X := 1 to 5 do

  Writeln(X);

この for 文では，変数 X の最初の値 (1) と最後の値 (5) を指定しています。この文を実行すると，X に最初の値が代入され，手続き Writeln によって X の現在値 1 が表示されます。次に，X の値に 1 が加算されて 2 になります。ここでXの値は最後の値 (5) よりも小さいので，手続き Writeln が再び実行され，X の現在値として 2 が表示されます。さらに処理が続き，X の値が最後の値 5 を超えると for 文の実行は終了します。

ループの最中には，制御変数の値を変更しないことが重要です。変更すると，エラーを引き起こします。

A counting example1073031

次に示すのは先に説明した for ループの変形です。この例では文字列グリッドコントロールとボタンを使用し，ユーザーによるボタンクリックで for ループを起動します。

作成したフォームは次のようになります。

ボタンの CountButtonClick イベントハンドラを次のように作成します。

procedure TForm1.CountButtonClick(Sender: TObject);

var

  Col: Integer;

begin

  for Col := 1 to 5 do

      StringGrid1.Cells[Col, 1] := IntToStr(Col);

end;

このイベントハンドラでは Cells プロパティを使用しています。このプロパティは，行の値と列の値をインデックスとした 2 次元の文字列配列です。配列についての詳細は「配列型」を参照してください。Cells プロパティの配列は文字列グリッドのセルを表しています。グリッド内の特定のセルにアクセスするには，セルの行の値と列の値を指定します。たとえば，グリッドの左上隅のセルは Cells[0, 0] です。これは列 0 の行 0 にあるセルを示します。このように，Cells 配列の最初の位置は 0 で示されます。

アプリケーションを実行して［Count］ボタンをクリックすると，CountButtonClick ハンドラの for 文は，文字列グリッドの 1 行目の列 1 から始まるそれぞれのセルに 1 から 5 までの数字を入れます。for 文を実行すると列の値は増加しますが，行の値は変化せず 1 のままです。

for 文では，予約語 downto を使って制御変数を指定の値まで減らしていくこともできます。そうするには，CountButtonClick ハンドラを次のように変更します。

procedure TForm1.CountButtonClick(Sender: TObject);

var

  Col: Integer;

begin

  for Col := 5 downto 1 do

      StringGrid1.Cells[Col, 1] := IntToStr(Col);

end;

アプリケーションを実行して［Count］ボタンをクリックすると，最終的な結果は変わりませんが，このコードでは列 5 から列 1 に向かって表示されます。コードを実行すると，Col 変数に値 5 が代入され，最後の値 1 より小さくなるまで減算されていきます。

Using nested for loops1073032

テーブルやグリッドにデータを表示する場合などは，for ループ内に別の for ループを記述すると便利です。次の文字列グリッドを例にして説明します。このコードでは，グリッドのスクロールしない固定領域に行と列のタイトルを表示し，各セルには行と列の座標を表示します。これらは［Show Coordinates］ボタンをクリックすると表示されます。

StringGrid1 のプロパティは次のようになります。RowCount は 6，ColCount は 6，DefaultColWidth は 105 です。また Button1 の Name プロパティは ShowCoordinatesButton になります。

［ShowCoordirates］ボタンのイベントハンドラを次のように作成します。

procedure TForm1.ShowCoordinatesButtonClick(Sender: TObject);

var

  Col, Row: Integer;

begin

  for Col := 1 to 5 do

    StringGrid1.Cells[Col, 0] := 'Col ' + IntToStr(Col);

  for Row := 1 to 5 do

    StringGrid1.Cells[0, Row] := 'Row ' + IntToStr(Row);

  for Col := 1 to 5 do

    for Row := 1 to 5 do

      StringGrid1.Cells[Col, Row] :=

        'Col ' + IntToStr(Col) + ', ' + 'Row ' + IntToStr(Row);

end;

このイベントハンドラには 4 つの for 文があります。最初の for 文では，文字列‘Col’と文字列に変換した Col 変数の現在値を行 0 に表示しています。

for Col := 1 to 5 do

  StringGrid1.Cells[Col, 0] := 'Col ' + IntToStr(Col);

2 番目の for 文では，文字列‘Row’と文字列に変換した Row 変数の現在値を列0に表示しています。

for Row := 1 to 5 do

  StringGrid1.Cells[0, Row] := 'Row ' + IntToStr(Row);

4 番目の for 文は 3 番目の for 文の中にネストされています。この 2 つの for 文では，各セルに行と列の座標を表示しています。

for Col := 1 to 5 do

  for Row := 1 to 5 do

    StringGrid1.Cells[Col, Row] :=

      'Col ' + IntToStr(Col) + ', ' + 'Row ' + IntToStr(Row);

まず，Col はグリッドの最初のスクロール列を示す値 1 を受け取ります。その直後に，2 番目の for ループが開始され，Row にグリッドのスクロール列の最初の行を示す値 1 が代入されます。その次のコードは，列 1 の行 1 に文字列を表示します。この文字列を構成するのは，部分文字列 'Col'，Col 変数の文字列値，部分文字列 ','，部分文字列 'Row'，Row 変数の文字列値です。Cells[1,1] に実際に表示される値は文字列「Col1，Row1」になります。

ネストされた for ループが実行されている間は，Col 変数の値は 1 のままなので，同じ列のそれぞれの行に対して表示が行われます。Row の値が 1 から 5 まで増加して列 1 の各行に値を書き込んだ後，ネストされた for ループは終了します。3 番目の (外側の) for ループは引き続き実行され，Col 変数の値を 1 つ増加します。この新しい Col 値に対して，再びネストされた for ループが実行されます。

Deciding which loop to use1073033

この節では 3 種類の Object Pascal ループについて説明しました。どの種類のループを使うかについては以下のガイドラインを参考にしてください。

ループを特定の回数だけ実行する場合は，for ループを使う
for ループは非常に高速で効率的です。

ループの実行回数が未定で，最低 1 回は実行させる場合は，repeat..until ループを使う

ループの実行回数が未定で，1 回も実行させない可能性がある場合は，while..do ループを使う


Object Pascal blocks
Object Pascal blocks1073034

Section topics	参照

ブロックは Object Pascal の重要な概念です。ブロックはアプリケーションの構造の元であり，変数やプロパティなどのスコープを決定します。なお，スコープについての詳細は「スコープ」を参照してください。

Object Pascal のブロックは省略可能な宣言部と実行部の 2 つで構成されます。宣言部がある場合は，必ず実行部の前に記述します。

宣言はコンパイラに情報を提供します。Object Pascal で使用できる宣言は，以下のとおりです。

変数宣言

定数宣言

型宣言

ラベル宣言

手続き，関数，メソッドの宣言

宣言部の後には，ブロックの実行部を続けます。ブロックの実行部には，実行するアルゴリズムの内容を記述します。同じブロック内に宣言部がある場合，実行部では宣言部で宣言された項目が使用されます。


Blocks within event handlers
Blocks within event handlers1073035

Section topics	参照

Delphi のブロックで最も一般的なのは，イベントハンドラ内のブロックです。次に示す簡単なイベントハンドラには実行部だけがあり，宣言部はありません。

procedure TForm1.Button1Click(Sender: TObject);

begin	{ブロックは実行部から始まる}

  Edit1.Text := 'Welcome to Delphi';

end;	{実行部の最後でブロックは終わる}

実行部は予約語 begin で始まり，予約語 end で終わります。

ブロックにはオプションとして宣言部が入ることもあります。上のイベントハンドラに宣言部を追加した例を次に示します。

procedure TForm1.Button1Click(Sender: TObject);

var	{ブロックは宣言部から始まる}

  Name: string;

begin	{ブロックの実行部の始まり}

  Name := Edit1.Text;

  Edit2.Text := 'Welcome to Delphi, ' + Name;

end;	{ブロックの終わり}

このイベントハンドラでわかるように，変数宣言部は予約語 var で始まり，実行部の前で終わります。

すでに述べたように，イベントハンドラは Object Pascal の手続きです。イベントハンドラもイベントハンドラ以外の手続きも，ブロックの形式は同じです。関数も手続きと似ています。手続きと関数についての詳細は，「手続きと関数」を参照してください。


Blocks within units
Blocks within units1073036

Section topics	参照

ユニット内のブロックも宣言部と実行部で構成されます。ユニット独自の部分もいくつかありますが，ブロック自体の考え方は同じです。次に例を示します。

unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Apps;

type	{宣言部とユニットブロックの始まり}

  TForm1 = class(TForm)

    Edit1: TEdit;

    Edit2: TEdit;

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    {Private 宣言}

  public

    {Public 宣言}

  end;

var

  Form1: TForm1;	{宣言部の終わり}

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);	{イベントハンドラブロックの始まり}

var

  Name: string;

begin

  Name := Edit1.Text;

  Edit2.Text := 'Welcome to Delphi, ' + Name;

end;	{イベントハンドラブロックの終わり}

end.	{ユニットブロックの終わり}

ユニットについての詳細は，「Object Pascal のユニット」を参照してください。ユニットの詳細とその構文解析図については，オンラインヘルプも参照してください。


Blocks within blocks
Blocks within blocks1073037

Section topics	参照

ブロックにはほかのブロックを入れることができます。たとえば，先の例ではプロジェクトブロック内のユニット 1 ブロックの中に Button1Click イベントハンドラのブロックが入っています。次の図はアプリケーション内のブロックの構造を示しています。

すべての Delphi アプリケーションの基本構造は同じです。複雑なアプリケーションも，基本構造に新しいコードのブロックを追加しただけです。たとえば，新しいイベントハンドラをユニットに追加したり，新しいユニットをプロジェクトに追加したりします。


Understanding scope
Understanding scope1073038

Section topics	参照

スコープは，変数，定数，メソッド，型などの識別子がアクティブとなる場所を定義するものです。識別子は，識別子が宣言されている最も内側のブロックのローカルスコープになります。

アプリケーションが，識別子を宣言したブロックの外のコードを実行しているとき，識別子は実行コードのスコープ外にあります。つまり，その識別子は使用できません。コードの実行が識別子の宣言があるブロックに入ったとき，この識別子にアクセスできます。

前の節ではブロックを紹介しました。プロジェクトに 2 つのユニットがあり，各ユニットに 3 つのイベントハンドラ (手続き) があるとします。このプロジェクトを図示すると，次のようになります。

それぞれの四角形はブロックを表します。手続き D 内で変数を宣言すると，この変数は手続き D のローカルスコープになるので，この変数にアクセスできるのは手続き D 内のコードに限られます。ユニット B で変数を宣言すると，この変数はユニット B のスコープ内にあるすべての手続き (D，E，F) で使用できます。この場合，この変数はユニット B のローカルスコープですが，ユニット B 内の手続きからみるとグローバルスコープとなります。

通常，識別子はできるだけローカルなスコープとして宣言します。その方がアプリケーションのデータを不用意に変更してしまう恐れが少なくなります。複数のブロック間でデータを共有したい場合に限って，グローバルスコープを使うことを考えます。


Accessing declarations that are not within scope
Accessing declarations that are not within scope1073039

Section topics	参照

現在のブロックのスコープ外にあるブロックの宣言も参照できます。たとえば，あるユニットで作成した支払い利息を計算するイベントハンドラをほかのユニットから使用する，というようなことが可能です。

スコープ外で宣言された識別子を参照するには次のようにします。

宣言のあるブロック名と宣言名を並べて，両者をピリオド (.) で区切る

たとえば，Unit1 に宣言されている手続き CalculateInterest を Unit2 から使用するには，次のような呼び出しを記述します。

Unit1.ComputeInterest(Principal, InterestRate: Double);

なお，Unit2 の uses 節には Unit1 を追加しておきます。uses 節にユニットを追加する方法についての詳細は，「ユニットの使い方」を参照してください。


A scope example
A scope example1073040

Section topics	参照

次にローカルスコープとグローバルスコープの例を示します。このようなフォームを使用します。ユーザーが最初の 2 つの編集ボックスに数値をそれぞれ入力して［Multiply］を選択すると，アプリケーションは 2 つの数値を掛け算して結果を答の編集ボックスに表示します。

［Multiply］ボタンの OnClick イベントハンドラを作成します。

procedure TForm1.MultiplyClick(Sender: TObject);	{2 つの数値を乗算する}

var

  FirstNumber, SecondNumber: Integer;

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber * SecondNumber);	{Edit3 に答を表示する}

end;

アプリケーションを実行すると，最初の編集ボックスに 1 つの整数を，2 番目の編集ボックスにもう 1 つの整数を入力します。［Multiply］ボタンをクリックすると，2 つの数値が掛け算され，結果が 3 番目の編集ボックスに表示されます。

フォームに別のボタンを追加して，ボタン名を Divide とします。

次のイベントハンドラを作成します。

procedure TForm1.DivideClick(Sender: TObject);

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber div SecondNumber);

end;

アプリケーションをコンパイル，実行すると，「Unknown identifier」というエラーメッセージが表示されます。MultiplyClick イベントハンドラでは，すでに FirstNumber と SecondNumber の 2 つの変数を宣言しています。しかし，これらの変数は DivideClick イベントハンドラでは使用できません。アプリケーションのコードは，変数を宣言したイベントハンドラの外からは，その変数にアクセスできないからです。実際，変数を宣言したイベントハンドラ外にコードの実行が移ると，その変数はメモリ上から削除されます。このことは，イベントハンドラに限らず，手続き，関数，メソッドのあらゆるルーチン内に宣言されたすべての識別子に当てはまります。このような識別子はローカルスコープであるといわれます。

アプリケーションを正しく実行するには，以下のいずれかの方法で対応します。

DivideClick イベントハンドラの中で FirstNumber 変数と SecondNumber 変数をローカルスコープとして再宣言する

procedure TForm1.DivideClick(Sender: TObject);

var

  FirstNumber, SecondNumber: Integer;

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber div SecondNumber);

end;

MultiplyClick イベントハンドラの変数宣言部を両方のイベントハンドラより上の階層に移動し，implementation 行と {$R *.DFM} 指令の下に挿入する。このコードの implementation 部以下の部分は次のようになります。

implementation

{$R *.DFM}

var

  FirstNumber, SecondNumber: Integer;	{イベントハンドラ用のグローバル変数}

procedure TForm1.MultiplyClick(Sender: TObject);	{2 つの数値を乗算する}

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber * SecondNumber);	{Edit3 に結果を表示する}

end;

procedure TForm1.DivideClick(Sender: TObject);	{最初の数値を 2 番目の数値で割る}

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber div SecondNumber);	{Edit3 に結果を表示する}

end;

...

2 番目の方法に従うと，FirstNumber と SecondNumber はイベントハンドラのローカルスコープではなくなり，どのイベントハンドラからでも使用できるようになります。今後追加するイベントハンドラから使用することもできます。したがって，この 2 つの変数はグローバルスコープであるといわれます。単にグローバル変数とも呼ばれます。ただし，この 2 つの変数はユニットブロック内で宣言されているので，ユニットに対してはローカルスコープです。

すでに述べたように，変数はできるだけローカルにします。ローカルな変数の方が，変数の使用場所がわからなくなったり，コードで変数の値を変更したときに思わぬ副作用を生じたりすることが少なくなります。したがって，前述の 2 つの方法では，最初の方法を優先的に考えます。2 番目の方法のように変数をグローバルにするのは，異なるブロックでデータを共有する場合に限ってください。

どちらの方法でも必要な変数にアクセスできるので，コードは正しく実行されます。もっとも，この例では整数値だけを使用しているため，FirstNumber の値を SecondNumber の値で割り切れない場合は，割り算の結果から小数部が失われます。

Redeclaring identifiers in a different scope1073041

同一の識別子をアプリケーションの複数の場所で宣言できます。識別子のスコープが異なる限り，これには何の問題もありません。コンパイラでは最もローカルなスコープの変数だけをアクセスするからです。

この節では，2 つのイベントハンドラ内で同じ FirstNumber 変数と SecondNumber 変数をそれぞれ宣言する方法をすでに解説しました。MultiplyClick と DivideClick という異なるイベントハンドラで宣言したそれぞれの識別子は，スコープが異なります。スコープが異なる 2 つのイベントハンドラ内では，同じ名前の識別子を宣言しても問題ありません。

FirstNumber をユニットのスコープ内で宣言し，さらにユニット内のイベントハンドラのスコープ内で宣言したとします。この場合も，アプリケーションを問題なくコンパイルできます。ただし，コンパイラがコード内で FirstNumber 変数を見つけたときに使用するのは，その場所からアクセスできる最もローカルな変数です。

Using a global variable1073042

アプリケーションの実行中に行った計算の数を記録するため，フォームを次のように変更します。

各イベントハンドラに次のコードを追加します。

Count := Count + 1;

Counter.Text := IntToStr(Count);

上のコード行では，フォームのボタンのどれかをクリックすると Count 変数に 1 を加算し，結果を Counter 編集ボックスに表示します。

ここでアプリケーションを実行しようとすると，Count 変数を宣言していないことを通知されます。そこで，各イベントハンドラにおいて，初期値 0 で Count を宣言してみます。DivideClick イベントハンドラは次のようになります。

procedure TForm1.DivideClick(Sender: TObject);

var

  FirstNumber, SecondNumber, Count: Integer;

begin

  Count := 0;

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber div SecondNumber);

  Count := Count + 1;

  Counter.Text := IntToStr(Count);

end;

いずれかのイベントハンドラが実行されるごとに，Count は 0 にリセットされてから 1 だけ増加します。これでは，アプリケーションでは 1 しか表示されません。

この場合，アプリケーションを正しく動作させるにはグローバル変数を使います。

Count の宣言をイベントハンドラのスコープ外に出し，ユニットの implementation 部で宣言します。これで Count はユニットのスコープ内に移動します。

...

implementation

{$R *.DFM}

var

  Count: Integer;

procedure TForm1.MultiplyClick(Sender: TObject);

...

［Multiply］ボタンまたは［Divide］ボタンをクリックするごとに Count が 0 にリセットされないように，ユニットの initialization 部で Count を初期化します。initialization 部を作成するには，予約語 initialization と Count の初期化コードをユニット最後の予約語 end の前に記述します。このブロックは次のようになります。

initialization

  Count := 0;

end.

アプリケーションを実行し，Edit1 と Edit2 に値を入力します。いずれかのボタンをクリックするごとに Count に 1 が加算されます。

両方のイベントハンドラで Count の値にアクセスして変更するので，両方のイベントハンドラに対して Count をグローバル変数として宣言したわけです。

メモ	よりオブジェクト指向的な方法で同じ目的を達成するには，Count をフォームオブジェクトのフィールドにします。この方法でも，フォームのすべてのイベントハンドラから Count を使用できます。オブジェクトとフィールドについての詳細は，「Delphi オブジェクトを使ったプログラミング」を参照してください。


Writing a procedure or function
Writing a procedure or function1073043

Section topics	参照

Delphi アプリケーションの開発中に記述するコードの大半は，Delphi が作成するイベントハンドラに入ります。しかし，イベントハンドラではない独自の手続きや関数を記述したい場合もあります。

たとえば，複数のイベントハンドラで共通な処理を行うために，同じコードを何度も繰り返して記述するのは面倒です。このようなコードは，イベントハンドラ外に出して独立した手続きや関数にします。そうすれば，ほかの既存の手続きや関数と同じように，どのイベントハンドラからもそのコードを呼び出すことができます。この方法には 2 つの利点があります。コードを 1 回だけ記述すればよいことと，イベントハンドラ内のコードが複雑にならないことです。

次の例では，前の節で説明したスコープの例を続けて使用します。implementation 部以降のコードを次に示します。

...

implementation

{$R *.DFM}

var

  Count: Integer;

procedure TForm1.MultiplyClick(Sender: TObject);

var

  FirstNumber, SecondNumber: Integer;

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber * SecondNumber);

  Count := Count + 1;

  Counter.Text := IntToStr(Count);

end;

procedure TForm1.DivideClick(Sender: TObject);

var

  FirstNumber, SecondNumber: Integer;

begin

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber div SecondNumber);

  Count := Count + 1;

  Counter.Text := IntToStr(Count);

end;

initialization

  Count := 0;

end.

ここまでのアプリケーションでは，ユーザーが誤ったデータを入力する可能性を考慮していません。たとえば，ユーザーが 2 つの編集ボックスの一方に値を入力せずにボタンをクリックした場合，アプリケーションは実行を中止してしまいます。これを避けるには，編集ボックスの値をチェックするコードを記述し，値が見つからないときはユーザーに値を再入力させるようにします。このコードは 2 つのイベントハンドラに別々に書くのではなく，1 回だけ記述して各イベントハンドラから呼び出すことにします。

ユニットの implementation 部で，すべてのイベントハンドラより前に NoValue 関数を記述します。

function NoValue(AnEditBox: TEdit): Boolean;

begin

  if AnEditBox.Text = '' then

  begin

    AnEditBox.Color := clRed;

    AnEditBox.Text := 'Enter a value';

    Result := True;

  end

  else

  begin

    AnEditBox.Color := clWindow;

    Result := False;

  end;

end;

NoValue 関数では，この関数に渡された編集ボックスが空かどうかを判定します。空の場合は編集ボックスを赤色にし，ユーザーに値の入力を要求した上で，True を返します。編集ボックスが空でない場合は，編集ボックスの色を Windows システムウィンドウの色に設定し，False を返します。

2 つのイベントハンドラから NoValue 関数を呼び出します。MultiplyClick イベントハンドラからの呼び出し (2 回呼び出しています) を次に示します。

procedure TForm1.MultiplyClick(Sender: TObject);

var

  FirstNumber, SecondNumber: Integer;

begin

  if NoValue(Edit1) or NoValue(Edit2) then	{この行では NoValue を 2 回呼び出す}

    Exit;	{編集ボックスが空であれば，このイベントハンドラを終了する}

  FirstNumber := StrToInt(Edit1.Text);

  SecondNumber := StrToInt(Edit2.Text);

  Edit3.Text := IntToStr(FirstNumber * SecondNumber);

  Count := Count + 1;

  Counter.Text := IntToStr(Count);

end;

どちらかの関数の呼び出しが True を返して 2 つの編集ボックスの両方または一方が空であることを示すと，手続き Exit が実行されます。Exit はランタイムライブラリのルーチンであり，現在のブロック内で進行中のコードの実行を中止します。つまり，MultiplyClick イベントハンドラの残りのコード行の実行を中止します。

アプリケーションを実行し，どちらかの編集ボックスに入力を忘れると，ユーザーはそのことを通知されます。

手続きと関数は以下の部分から構成されます。

ヘッダー

コードのブロック


Writing a procedure or function header
Writing a procedure or function header1073044

Section topics	参照

手続きや関数は，手続きや関数を識別するヘッダーで始まります。ヘッダーには必要なパラメータのリストを付けます。手続きは予約語 procedure で，関数は予約語 function で始めます。

パラメータは丸カッコ内に入れます。通常，各パラメータには識別名と型を指定します。パラメータリスト内のパラメータ間はセミコロン (;) で区切ります。次に例を示します。

procedure ValidateDate(Day: Integer; Month: Integer; Year: Integer);

同じ型のパラメータは次のように連結できます。

procedure ValidateDate(Day, Month, Year: Integer);

パラメータについての詳細は，「パラメータの受け渡し」を参照してください。

関数の場合，ヘッダーには戻り値の型も記述します。ここには，関数の返す値の型を指定します。戻り値とヘッダーのほかの部分とを区別するために，コロン (:) で区切ります。たとえば，次の関数の戻り値は Double 型です。

function CalculateInterest(Principal, InterestRate: Double): Double;

すべてのヘッダーはセミコロン (;) で終了します。


Writing a procedure or function block
Writing a procedure or function block1073045

Section topics	参照

「Object Pascal のブロック」で前述したように，すべてのブロックは宣言部 (省略可能) と実行部の 2 つの部分で構成されます。

Declarations within a procedure or function block1073046

手続きブロックまたは関数ブロック内の宣言部では，以下の宣言が行えます。

型宣言

変数宣言

定数宣言

Type declarations1073047

Delphi アプリケーションでは，Object Pascal 言語に組み込まれた定義済みのデータ型とは別に新しい型を作成できます。ユーザー定義型の作成についての詳細は，「新しいデータ型の定義」を参照してください。ここでは型宣言部を簡単に示すことにします。型宣言部は予約語 type で始めます。型宣言の例をいくつか次に示します。

type

  TCount = Integer;

  TPrimaryColor = (Red, Yellow, Blue);

  TTestIndex = 1..100;

  TTestValue = -99..99;

  TTestList = array[TTestIndex] of TTestValue;

  TCharVal = Ord('A')..Ord('Z');

  TDays = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

型識別子の後には等号 (=) を続けます。その後には，新しい型を構成する値を定義します。この例では，TCount 型の変数は Integer 値になります。TPrimaryColor 型の変数は Red，Yellow，Blue のいずれかに限られます。TCharVal 型の変数は大文字 A～Z の Ord 関数値の範囲内になければなりません。

なお，ここでは型の名前は文字Tで始めます。これは必須ではありませんが，Delphi のドキュメントで使用している命名規則であり，型名をほかの識別子から区別するのに便利です。

変数宣言や定数宣言と同じように，型宣言のスコープは宣言の場所に応じてグローバルにもローカルにもなります。たとえば，手続き内で TDays 型を宣言すると，TDays 型はローカルスコープとなり，この手続きの実行中に限り使用できます。一方，implementation 部の最初に型宣言を記述すると，ユニット内のすべての手続き (イベントハンドラを含む) や関数で使用できます。

Variable and constant declarations1073048

変数や定数をイベントハンドラ内で宣言する方法について，「変数の宣言」と「定数の宣言」で解説しました。イベントハンドラは手続きなので，手続きや関数の変数宣言と定数宣言は同様の方法で行えます。

Ordering the declaration parts1073049

従来，手続きや関数の中で，型宣言は変数宣言の前に記述し，変数宣言は定数宣言の前に記述していました。しかし，宣言部を並べる順番は自由です。同じ種類の宣言部を複数記述することもできます。たとえば，複数の変数宣言部があってもかまいません。唯一の規則は，手続きや関数のヘッダーと実行部つまりコードの部分の間に宣言を記述しなければならない点です。

Writing the statement part1073050

手続きや関数の実行部は予約語 begin で始めて予約語 end で終了し，最後にセミコロン (;) を付けます。begin..end ブロック内のすべてのコードは，手続きまたは関数の文です。すでに述べたように，文としては代入文，手続き呼び出し，関数呼び出し，if 文，case 文，ループを使用できます。

Assigning a return value in a function1073051

関数は値を返すので必ず戻り値の代入先を指定します。それには 2 つの方法があります。

戻り値を関数の名前に代入する

戻り値を Result 変数に代入する

次の例では最初の方法を示します。つまり，戻り値を関数の名前に代入します。

function CalculateInterest(Principal, InterestRate: Double): Double;

begin

  CalculateInterest := Principal * InterestRate;

end;

次の例では 2 番目の方法を示します。最初の例と同じ結果になりますが，戻り値の代入先を Result 変数にします。この場合，どの関数でも Result を使用します。

function CalculateInterest(Principal, InterestRate: Double): Double;

begin

  Result := Principal * InterestRate;

end;

Result 変数を宣言する必要はありません。この変数は自動的に使用可能になります。Result を使うとコードは少しわかりやすくなります。

どちらの方法でも関数呼び出しは同じです。たとえば，CalculateInterest 関数が内部的に CalculateInterest と Result のどちらに値を代入していても，次の関数呼び出しは同じ結果になります。

InterestEarned := CalculateInterest(1000, 0.08);


Positioning a procedure or function in your code
Positioning a procedure or function in your code1073052

Section topics	参照

手続きと関数はユニットの implementation 部に記述します。implementation 部で宣言した識別子を使用できるのは同じユニット内のコードだけです。

しかし，独自に記述した手続きや関数をほかのユニットのコードからも使用できるように設定することもできます。

手続きや関数をほかのユニットから使用する方法は，次のとおりです。

1.	手続きや関数のヘッダーをユニットの interface 部に記述します。
ヘッダーを interface 部に記述すると，このルーチンを interface 部で宣言することになります。つまり，このユニットを使用するほかのすべてのユニットでこのルーチンを使用できるようになります。

2.	手続きや関数の全体 (ヘッダーと実装) をユニットの implementation 部に記述します。

3.	ルーチンを宣言したユニットの名前を，このルーチンにアクセスさせるユニットの uses 節に追加します。

ユニット，uses 節，ほかのユニットで宣言されたルーチンの使い方についての詳細は，「Object Pascal のユニット」を参照してください。

たとえば，「手続きと関数」で説明した NoValue 関数はユニットの interface 部で宣言することもできます。さらにルーチンの本体，つまり実装をユニットの implementation 部に記述します。この場合のユニットのスケルトンを次に示します。

unit Unit1;

interface

uses

...

type

  TForm1 = class(TForm)

    Multiply: TButton;

    Divide: TButton;

    procedure MultiplyClick(Sender: TObject);

    procedure DivideClick(Sender: TObject);

  ...

  end;

var

  Form1: TForm1;

function NoValue(AnEditBox: TEdit): Boolean;

implementation

function NoValue(AnEditBox: TEdit): Boolean;

...

end;

procedure TForm1.MultiplyClick(Sender: TObject);

...

end;

procedure TForm1.DivideClick(Sender: TObject);

...

end;

end.

NoValue 関数を interface 部で宣言せず，implementation 部だけでのみ宣言すると，NoValueを使用できるのはこのユニットだけになります。

Delphi でイベントハンドラを作成すると，このイベントハンドラ (手続き) はオブジェクトの型宣言の中で宣言されます。オブジェクトの型宣言はユニットの interface 部にあるので，ほかのすべてのユニットでこのイベントハンドラを呼び出すことができます。なお，ユニットの interface (インターフェース) 部と implementation (実現) 部についての詳細は，「Object Pascal のユニット」を参照してください。また，オブジェクトの型宣言についての詳細は「Delphi オブジェクトを使ったプログラミング」を参照してください。

「手続きと関数」で示した NoValue は，implementation 部でだけ宣言するルーチンの例です。イベントハンドラ内のコードからのみ NoValue を使用する場合は，そのルーチンをユニットの interface 部では宣言せず，implementation 部でのみ宣言します。イベントハンドラのコードは implementation 部に記述します。

メモ	NoValue は，これを使用するイベントハンドラの前に挿入します。NoValue 関数をイベントハンドラの後に宣言すると，コンパイラはハンドラの識別子 NoValue が未定義の識別子であると報告します。

手続きや関数を最初に宣言する場所は，これを使用するすべてのルーチンより前でなければなりません。手続きや関数の宣言か，または手続きや関数自体を記述します。これを使用するルーチンがイベントハンドラである場合も独自に記述したルーチンである場合も同様です。つまり，ルーチンでほかのルーチンを使用するには，使用されるルーチンを先に宣言します。Object Pascal の規則では，識別子は必ず宣言してから使用しなければなりません。

Forward declarations1073053

上記の規則には例外があります。実はルーチン A からルーチン B を呼び出し，さらにこのルーチン B からルーチン A を呼び出すことができます。このような呼び出し関係は相互再帰であるといいます。

ルーチンを相互再帰的に呼び出すには，ルーチンを forward 宣言します。forward 標準指令でルーチンを宣言すれば，手続きや関数の実装を任意の場所に記述できます。イベントハンドラの間や，このルーチンを呼び出すほかの手続きや関数の後でもかまいません。NoValue を forward 宣言した場合を次に示します。

function NoValue (AnEditBox: TEdit): Boolean; forward;

forward 宣言では forward 標準指令を使用します。この宣言は手続きの実装を含まないので，NoValue の実装は forward 宣言の後の任意の場所で記述します。

NoValue の実装は，この手続きを呼び出すほかの手続き，関数，イベントハンドラ，メソッドの後にあってもかまいません。

2 つの手続きが互いに再帰的に呼び出す例を次に示します。このアプリケーションのフォームには 1 つのボタンがあります。このボタンをクリックすると，2 つの手続きは互いを呼び出し始めます。

unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Apps;

type

  TForm1 = class(TForm)

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

var

  Alpha: Integer;

procedure Test2(var A : Integer); forward;	{Test2 は forward 手続きとして宣言する}

procedure Test1(var A: Integer);

begin

  A := A - 1;

  if A > 0 then

    Test2(A);	{手続き Test2 の呼び出し}

  Writeln(A);

end;

procedure Test2(var A: Integer);

begin

  A := A div 2;

  if A > 0 then

    Test1(A);	{手続き Test1 の呼び出し}

  Writeln(A);

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

  Alpha := 15;	{Alpha 変数に初期値を代入する}

  Test1(Alpha);	{手続き Test1 の最初の呼び出し}

end;

end.

ボタンの OnClick イベントハンドラのコードでは，Alpha 変数に値を渡して手続き Test1 を呼び出します。Test1 では Alpha 変数の値から 1 を差し引き，さらに Alpha が 0 よりも大きいかどうかを判定します。0 よりも大きい場合，Test1は手続き Test2 を呼び出します。Test2 では Alpha 変数の値を 2 で割り，さらに Alpha が 0 よりも大きいかどうかを判定します。0 よりも大きい場合，Test2 は Test1 を呼び出します。2 つの手続きは，Alpha が 0 になるまで相互に呼び出し合います。Alpha が 0 になると，手続きの Writeln 文が実行されます。

この章では，相互再帰の呼び出しについて詳しく説明する余裕はありません。ただし重要なことは，手続き Test2 が Test1，Test2，Button1Click イベントハンドラの実装の前で forward 手続きとして宣言されているということです。Test2 を forward 手続きとして宣言しないと，プロジェクトをコンパイルできません。宣言されていない Test2 を呼び出していることになるからです。


Passing parameters
Passing parameters1073054

Section topics	参照

手続きや関数を呼び出すときに，呼び出された側の手続きや関数にパラメータをとおしてデータを渡す場合がよくあります。手続きの呼び出しでパラメータを使う方法は，「パラメータを指定した手続きの呼び出し」で解説しています。また，手続きや関数のヘッダーにパラメータリストを作成する方法は，「手続きと関数のヘッダー」で解説しています。この節では，手続きや関数で最も一般的に使用する種類のパラメータについて説明します。

値パラメータ

変数パラメータ

定数パラメータ

呼び出し側の手続きや関数で指定したパラメータは，実パラメータと呼ばれます。呼び出された側の手続きや関数の中の対応するパラメータは，仮パラメータと呼ばれます。次の手続き呼び出しには実パラメータ Edit1 があります。

ColorIt(Edit1);

これに対して，呼び出される側の手続き宣言の中のパラメータ AnEditBox は仮パラメータです。

procedure ColorIt(AnEditBox: TEdit);

Value parameters1073055

「forward 宣言」のコード例を除けば，この章では値パラメータだけを説明してきました。仮値パラメータは実値パラメータのコピーです。言いかえれば，コンパイラは実パラメータと仮パラメータを異なるメモリアドレスに配置します。したがって，呼び出された側の手続きや関数で仮パラメータの値を変更しても，実パラメータの値は変更されません。

次に例を示します。

ボタンに対して次の OnClick イベントハンドラを作成します。

procedure TForm1.Button1Click(Sender: TObject);

var

  Number: Integer;

begin

  Number := StrToInt(Edit1.Text);

  Calculate(Number);

  Edit2.Text := IntToStr(Number);

end;

ハンドラは，最初の編集ボックスにユーザーが入力した数値を取得して，Number 変数に代入します。この変数は手続き Calculate に渡されます。最後の行では，2 番目の編集ボックスに Number の値を表示します。

コード中のイベントハンドラの前，予約語 implementation とリソース指令 ({$R *.DFM}) の後に次の手続き Calculate を記述します。

procedure Calculate(CalcNo: Integer);

begin

  CalcNo:= CalcNo * 10;

end;

Calculate 手続きでは CalcNo パラメータの値が変わります。Calculate 手続き終了時の CalcNo の値は開始時の 10 倍です。

アプリケーションを実行し，Edit1 編集ボックスに数値を入力します。

Edit1 編集ボックスに入力した値は，Calculate に渡す前の Number の値です。Edit2 編集ボックスに表示される値は，Calculate を実行した後の Number の値です。ところが，Number の 2 つの値はまったく同じです。

CalcNo パラメータは Number パラメータのコピーにすぎません。CalcNo の値が大きく変わっても，Number の値は不変です。そして，このアプリケーションでは CalcNo の値を一切表示していません。

簡単な図を使って説明します。Number と CalcNo はコンピュータのメモリ上の別個のアドレスに存在します。次の図のボックスはメモリ上の位置を表します。Calculate が呼び出されると，Number の値は CalcNo のメモリアドレスにコピーされます。

Calculate の実行を開始したときの Number と CalcNo の値

手続き Calculate では CalcNo パラメータの値を変更するので，Calculate の実行終了後の Number と CalcNo の値は異なります。

Calculate 実行後の Number と CalcNo の値

値パラメータには式も使えます。式についての詳細はオンラインヘルプの「式」を参照してください。

Variable parameters1073056

呼び出された側の手続きや関数の処理によって，パラメータの値を変更させたい場合もあります。このような場合は変数パラメータを使います。変数パラメータを使用するには，呼び出された側のルーチンの仮パラメータの前に，予約語 var を挿入します。次に例を示します。

procedure Calculate(var CalcNo: Integer);

変数パラメータは実パラメータ (この例では Number) への参照です。つまり，変数パラメータは実パラメータを指し示すもので，メモリ内に独立した場所を持つわけではありません。

変数パラメータを渡した場合，仮パラメータに対する変更は実パラメータにも反映されます。両方のパラメータは同じ値を参照しているからです。

手続き Calculate に var を追加して，アプリケーションを実行し，Edit1 編集ボックスに数値を入力すると，手続き Calculate が OnClick イベントハンドラの Number 変数の値を変更します。実パラメータ Number と仮パラメータ CalcNo は同じ変数を参照しているので，Calculate を実行すると 2 番目の編集ボックスの Number 値が変わります。

実際に起こったことを次の図で示します。Calculate を呼び出した時点では，Number の値と CalcNo の値は同じです。実パラメータも仮パラメータも同じメモリ位置を参照するからです。

Calculate の実行を開始したときの Number と CalcNo の値

手続き Calculate を実行すると値が変わります。ここでも，Number パラメータと CalcNo パラメータは依然として同じ値を参照しています。

Calculate 実行後の Number と CalcNo の値

:

Constant parameters1073057

手続きや関数の実行中に値が変化しない仮パラメータについては，変数パラメータのかわりに定数パラメータを使用できます。仮パラメータを定数パラメータにするには，パラメータリスト内でパラメータ名の前に予約語 const を挿入します。

値パラメータと同じように，定数パラメータにはどんな式でも使用できます。値パラメータのかわりに定数パラメータを使うと，パラメータに間違ってほかの値を代入することがなくなります。そのため，パラメータの値を変更しない場合は定数パラメータの方が便利です。定数パラメータに値を代入しようとしても定数の値は変更できないので「Invalid variable reference」というメッセージが生成されます。

Deciding which kind of parameter to use1073058

パラメータを使用する場合は以下の点に注意してください。

実パラメータの値を変更したくない場合は，値パラメータを使用する。値パラメータでは，仮パラメータは実パラメータのコピーなので，実パラメータの値は不変です。
再度明記しますが，実パラメータは呼び出し側の手続きや関数で指定するパラメータを意味し，仮パラメータは呼び出された側のルーチンで指定するパラメータを意味します。

呼び出された側のルーチンで，渡したパラメータの値を変更させたい場合は，変数パラメータを使用する。変数パラメータでは，実パラメータも仮パラメータも同じ値を参照するので，呼び出された側のルーチンで仮パラメータが変更されると，実パラメータの値も変わります。

呼び出された側のルーチンで仮パラメータを変更しない場合は，このルーチンの仮パラメータとして定数パラメータを使用する。これにより，仮パラメータの値を変更したくないときに間違ってほかの値を代入する事態を防止できます。


Defining new data types
Defining new data types1073059

Section topics	参照

Object Pascal 言語には多数の定義済みデータ型があります。そのリストが表「変数の宣言」にあります。さらに，定義済みデータ型を利用して，アプリケーション固有のニーズに応じた新しいデータ型を作成できます。この節では，以下のような典型的な新しいデータ型の作成について説明します。

列挙型

部分範囲型

配列型

集合型

レコード型

オブジェクト型

Object Pascal には，ほかにもユーザー定義のデータ型としてファイル型，ポインタ型，手続き型がありますが，この章では取り上げません。ユーザー定義の各データ型についての詳細は，オンラインヘルプで各データ型を参照してください。


Enumerated types
Enumerated types1073060

Section topics	参照

列挙型の宣言では，この型が取り得るすべての値をリスト (列挙) します。列挙型の宣言の例を次に示します。

type

  TDays = (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);

  TPrimaryColor = (Red, Yellow, Blue);

  TDepartment = (Finance, Personnel, Engineering, Marketing, MIS);

  TDog = (Poodle, GoldenRetriever, Dachshund, NorwegianElkhound, Beagle);

上の各列挙型に対応する変数宣言の例を次に示します。

var

  DayOfWeek: TDays;

  Hue: TPrimaryColor;

  Department: TDepartment;

  DogBreed: TDog;

列挙型の宣言で丸カッコ内にリストされた各値には，リスト内の値の位置に従って整数値が割り当てられます。たとえば，TDays 型の宣言の Monday は 0，Tuesday は 1 という値を持っています。DayOfWeek 変数を Integer 型として宣言し，各曜日を表す整数値を代入しても同じことです。しかし，曜日や月などのように順番を持つものは整数値でも表せますが，順番を持たないものの場合にはあまり便利ではありません。たとえば，次の代入文を見てください。

DogBreed := Dachshund;

明らかに，上の文は次の文よりもはるかに具体的でわかりやすくなっています。

DogBreed := 2;

列挙型でリストされた値は識別子として宣言されます。したがって，アプリケーションに先の例の列挙型の宣言と変数の宣言がある場合，識別子 Finance が宣言されたことになり，たとえば変数としての Finance を別に宣言することはできません。

列挙型の使い方を実際に示します。次のように行ってください。

1.	フォームに 4 つのラジオボタン，1 つのラベル，1 つのボタンを配置します。ラジオボタンはグループボックス内に配置します。

2.	オブジェクトインスペクタを使って，以下のようにプロパティを変更します。

グループボックスの Caption プロパティを Select A Course に変更する

最初のラジオボタンに HistoryButton という名前を付け，Caption プロパティを History に変更する

2 番目のラジオボタンに LiteratureButton という名前を付け，Caption プロパティを Literature に変更する

3 番目のラジオボタンに BiologyButton という名前を付け，Caption プロパティを Biology に変更する

4 番目のラジオボタンに PsychologyButton という名前を付け，Caption プロパティを Psychology に変更する

ボタンの Caption プロパティを Display Selected Course に変更する

3.	予約語 implementation とリソース指令 ({$R *.DFM}) の下に TCourse 型を宣言し，さらに TCourse 型の SelectedCourse 変数を宣言します。

type

  TCourse = (Nothing, History, Literature, Biology, Psychology);

var

  SelectedCourse: TCourse;

4.	各ラジオボタンに OnClick イベントハンドラを作成します。完成したコードは次のとおりです。

...

implementation

{$R *.DFM}

type

  TCourse = (Nothing, History, Literature, Biology, Psychology);

var

  SelectedCourse: TCourse;

procedure TForm1.HistoryButtonClick(Sender: TObject);

begin

  SelectedCourse := History;

end;

procedure TForm1.LiteratureButtonClick(Sender: TObject);

begin

  SelectedCourse := Literature;

end;

procedure TForm1.BiologyButtonClick(Sender: TObject);

begin

  SelectedCourse := Biology;

end;

procedure TForm1.PsychologyButtonClick(Sender: TObject);

begin

  SelectedCourse := Psychology;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

case SelectedCourse of

   History: Label1.Caption := 'You are taking history';

   Literature: Label1.Caption := 'You are taking literature';

   Biology: Label1.Caption := 'You are taking biology';

   Psychology: Label1.Caption := 'You are taking psychology';

  else

     Label1.Caption := 'You are taking nothing';

end;

end;

...

5.	アプリケーションを実行します。

コースを選択するためにラジオボタンを選択すると，SelectedCourse 変数に列挙値が代入されます。ボタンの OnClick イベントハンドラは，case 文によって SelectedCourse 変数の値に応じた適切なメッセージを表示します。


Subrange types
Subrange types1073061

Section topics	参照

部分範囲型は，整数型，論理型，Char 型，列挙型の一定範囲の値を表します。部分範囲型は，変数に代入できる値の範囲を制限する場合に有用です。部分範囲型を作成するには，範囲の上限値と下限値を指定し，この間に 2 個のピリオドを記述します。次に例を示します。

1..100

部分範囲型は型宣言で新しい型として宣言します。例をいくつか示します。

type

  TCompassRange   = 0..360;

  TValidLetter    = 'A'..'F';

  TMonthlyIncome = 10000..30000;

  THours           = 0..23;

  TPrecipitation = (Drizzle, Showers, Rain, Downpour, Thunderstorm);	{列挙型}

  TRain            = Drizzle..Downpour;	{Tprecipitation の部分範囲}

次に，新しい部分範囲型を使用する簡単なアプリケーションを作成します。

ボタンの OnClick イベントのイベントハンドラを作成します。

procedure TForm1.Button1Click(Sender: TObject);

{$R+}

type

  TValidEntry = 1..100;

var

  Entry: TValidEntry;

begin

  Entry := StrToInt(Edit1.Text);

  Label2.Caption := 'Excellent!';

end;

アプリケーションを実行し，編集ボックスに 100 よりも大きい数値を入力し，ボタンをクリックすると，範囲チェックエラーを知らせる実行時エラーが発生します。1～100 の数値を入力すると，アプリケーションは問題なく実行します。

$R 指令を忘れずに使用してください。{$R+} はイベントハンドラの実行中に範囲チェックをオンにします。$R 指令を取り除くと，コンパイラは範囲外エラーを認識できません。コンパイラ指令についての詳細は，「コンパイラ指令」を参照してください。なお，範囲チェックをオンにするには，［プロジェクト(P)｜オプション(O)］を選択して［コンパイラ］ページの［範囲チェック(R)］を選択する方法もあります。


Array types
Array types1073062

Section topics	参照

配列は，特定の型のデータの順序集合です。集合の各要素は集合内の順番を表す数を使って指定します。配列を最初に作成した時点では要素に意味のある値は入っていませんが，その後でデータを入力し，必要に応じて参照，変更できます。Double 型の配列の変数宣言の例を次に示します。

var

  Check : array{1..10] of Double;

この宣言は，変数 Check が Double 型の 10 個の変数のリストを参照することを Delphi に伝えます。各変数には 1～10 の数値 (インデックス) が付きます。

配列の各項目は配列名と大カッコ ([ ]) 内に入れたインデックスで参照します。つまり，配列 Check の各変数は Check[1]，Check[2]，Check[3]，Check[4]，...，Check[10] となります。この各変数は，Double 型の変数としていつでも使用できます。なお，インデックス値は定数でなくてもかまいません。1～10 の範囲の整数を表す式も指定できます。次に例を示します。

J := 5;

Check[J] := 0.0;

上の文は変数 Check[5] に値 0.0 を代入します。Check は Double 型の配列なので，代入する値を実数にするため小数点を含めてあります。なお，すべての実数は必ず数字で始めなければなりません。したがって，先頭に小数点を使用することはできず，.0 ではなく 0.0 と記述します。

配列内のすべての Check 変数に 0 を代入する場合は，for ループを使用できます。インデックス値は変数でもかまわないので，配列のそれぞれの項目に代入文で値を代入するより for ループを使用する方が簡単です。次の for ループでは，10 個すべての Check に 0.0 を代入します。

for J := 1 to 10 do

  Check(J) := 0.0;

配列を型として定義することもできます。次に例を示します。

type

  TCheck = array[1..100] of Double;

これで，配列型の変数を宣言できます。たとえば，次のコードでは CheckingAccount を TCheck 型の変数として宣言しています。TCheck 型は 100 個の実数の配列です。

var

  CheckingAccount: TCheck;

Multidimensional arrays1073063

これまでに説明した配列は 1 次元のリストでしたが，配列は多次元にすることもできます。たとえば，2 次元配列を使えば表形式のデータを表せます。

次のコードは，20 列 20 行で構成された表のすべての値を保持する 2 次元配列型を宣言します。

type

  TTable = array[1..20, 1..20] of Double;

TTable 型の変数を宣言します。

var

  BigTable: TTable;

表のすべての値を 0.0 に初期化するには，ネストした for ループを使用します。

var

  Col, Row: Integer;

...

for Col := 1 to 20 do

  for Row:= 1 to 20 do

    BigTable[Col, Row] := 0.0

String types: Arrays of characters1073064

コントロールのキャプションに入力するテキストなどの文字列は，実際は1次元の文字配列 (Char 型の配列) です。Object Pascal では 2 種類の文字列，つまり長い文字列と短い文字列があります。

長い文字列には非常に多くの文字を入れられます。長い文字列のサイズは，代入する文字の長さによって動的に拡張/縮小します。長い文字列の変数は予約語 string を使って宣言します。

短い文字列は最大 255 文字までの文字を入れられます。短い文字列の変数を宣言するときは，配列型を宣言するときに配列のサイズを指定するのと同様に，文字列のサイズを指定します。

文字列型の宣言の例をいくつか次に示します。

type

  BigString: string;	{長い文字列}

  MyString: string[15];	{短い文字列}

  LittleString: string[1];	{最短の文字列}

この宣言では MyString 型を最大 15 文字，LittleString 型を 1 文字で宣言しています。BigString 型のようにサイズを指定しないと，文字列は長い文字列となります。

ほかのデータ型と同じように，これらの文字配列の変数を宣言できます。

var

  MyName: MyString;

  Letter, Digit: LittleString;

文字列型の変数やプロパティに値を代入するには，文字列を単引用符 (') で囲んで記述します。次に例を示します。

MyName := 'Frank P. Land';

Label1.Caption := 'File name';

MyName は 15 文字まで保持できる MyString 型の変数なので，MyName 変数は 'Frank P. Land' としてメモリに格納されます。MyName 変数に文字列 'Frank P. Borland' を代入すると，MyNameには 'Frank P. Borlan' だけが入ります。MyName 変数に入るのは 15 文字だけだからです。

Object Pascal の短い文字列は文字の配列としてメモリに格納されます。ただし，配列の実際のサイズは指定した文字列のサイズよりも 1 バイト大きくなります。文字列の最初の位置 [0] は文字列のサイズを入れるバイトだからです。

文字列は文字の配列なので，配列の場合と同じように文字列内の文字にもインデックス値でアクセスできます。次に例を示します。

MyName[1]

これは MyName 文字列変数内の最初の文字を指します。

文字列型の変数やプロパティを操作するには，Object Pascal の提供する豊富な演算子，手続き，関数を利用できます。次にランタイムライブラリの文字列処理ルーチンの例を紹介します。

ルーチン	説明
Concat	複数の文字列を連結して 1 つにする。正符号 (+) で文字列を連結することもできる
Copy	文字列内の部分文字列を返す
Delete	文字列の指定位置から指定数の文字を削除する
Insert	文字列内に別の文字列を挿入する
Length	文字列の長さを返す
Pos	文字列内の部分文字列の位置 (インデックス) を返す
文字列の手続きや関数についての詳細は，オンラインヘルプを参照してください。

Finding the length of a string1073065

次に，ユーザーが編集ボックスに入力した文字列の長さを調べる簡単な例を示します。

文字列処理の例

次のイベントハンドラを作成します。

procedure TForm1.FindLengthClick(Sender: TObject);

type

  TEditString = string;

var

  UserString: TEditString;

begin

  UserString := Edit1.Text;

  Label2.Caption := 'This string is ' + IntToStr(Length(UserString)) +

    ' characters in length';

end;

アプリケーションを実行し，ボタンをクリックすると，編集ボックスに入力した文字列の長さが Label2 コントロールに表示されます。

編集ボックスに入力したテキストは，UserString 変数に代入されます。

UserString := Edit1.Text;

UserString は TEditString 型なので，最大 255 文字まで入ります。

Length 関数は UserString の文字数を返します。

Length(UserString)

Length は Integer 値を返すので，これを文字列値に変換します。この変換は IntToStr 関数で行います。

IntToStr(Length(UserString))

Label2.Caption に代入された文字列は，以下の 3 つの部分文字列で構成されています。

'This string is '

IntToStr(Length(UserString))

' characters in length'

この 3 つの部分文字列は + 演算子で連結されて 1 つの文字列になります。

この例では文字列型を宣言し，この型の変数を使いました。このイベントハンドラはもっと簡潔に，次のように記述できます。

procedure TForm1.FindLengthClick(Sender: TObject);

begin

  Label2.Caption := 'This string is ' + IntToStr(Length(Edit1.Text)) +

     ' characters in length';

end;


Set types
Set types1073066

Section topics	参照

集合型は，特定の型の要素の集合です。この型には，整数型，論理型，Char 型，列挙型，部分範囲型を使用できます。集合型は，値が特定の集合に属するかどうかをチェックするのに有用です。

新しい集合型を使用する簡単なアプリケーションの例を次に示します。

ボタンの OnClick イベントのイベントハンドラを作成します。

procedure TForm1.Button1Click(Sender: TObject);

type

  TVowels = set of Char;

var

  Vowels: TVowels;

begin

Vowels := ['A','E','I','O','U'];

if Edit1.Text[1] in Vowels then

    Label2.Caption := 'You are clever'

else

    Label2.Caption := 'Please try again';

end;

新しい TVowels 型は Char 型の集合です。Vowels は TVowels 型の変数として宣言されています。予約語 begin に続く最初のコード行で母音の集合を作成し，この新しい集合を Vowels 変数に代入します。なお，次の代入文は Vowels を要素を含まない集合にします。

Vowels := [];

このような集合は空の集合と呼ばれます。

if 文では，編集ボックスに入力した値が Vowels 集合内にあるかどうかを，in 演算子で確認しています。式 Edit1.Text[1] in Vowels は，True または False のどちらかに評価される論理式です。この式は Text 文字列内の最初の文字が Vowels 集合内にあるかどうかをテストします。


Record types
Record types1073067

Section topics	参照

レコードは，アプリケーションで一括操作できるデータの集合体です。たとえば，次のように宣言した TEmployee レコード型を使用できます。

type

  TEmployee = record

    LastName : string[20];

    FirstName: string[15];

    YearHired: 1990..2000;

    Salary: Double;

    Position: string[20]

  end;

レコードにはデータの値を入れるフィールドがあります。各フィールドはデータ型を持っています。TEmployee 型のフィールドは LastName，FirstName，YearHired，Salary，Position です。各フィールドに個別にアクセスすることもレコード全体を操作することもできます。

たとえば，ここに 2 つのレコード変数を宣言します。

var

  NewEmployee, PromotedEmployee: TEmployee;

コードで NewEmployee レコードの Salary フィールドを参照するには，次のように記述します。

NewEmployee.Salary := 43500.00

レコードを単一の対象として操作することもできます。

PromotedEmployee := NewEmployee;

レコード内のフィールドを参照する場合は，レコード名，ピリオド (.) ，フィールド名を順に記述します。

PromotedEmployee.Position

あるレコード内の複数のフィールドに値を代入する場合は，with 文を使用できます。まず，with 文を使用しないコードを示します。

PromotedEmployee.LastName := 'Jeffries';

PromotedEmployee.FirstName := 'Richard';

PromotedEmployee.YearHired := 1990;

PromotedEmployee.Salary := 100000.00;

PromotedEmployee.Position := 'Senior technical writer';

次に，with 文を使用して値を代入するコードを示します。

with PromotedEmployee do

  begin

    LastName := 'Jeffries';

    FirstName := 'Richard';

    YearHired := 1990;

    Salary := 100000;

    Position := 'Senior technical writer';

  end;


A few words about objects
A few words about objects1073068

Section topics	参照

オブジェクトは Delphi のプログラミングで非常に重要な役割を果たすデータ型で，ユーザーが定義することもできます。オブジェクトは，レコードと同じように構造を持ったデータ型であり，値を保持するフィールドを持ちます。さらに，オブジェクトにはメソッドを定義できます。メソッドとはオブジェクトのフィールド内のデータに作用する手続きや関数のことです。

フォームに新しいコンポーネントを追加すると，フォームオブジェクトにフィールドを追加したことになります。各コンポーネントもオブジェクトであり，イベントに応答できるようにコンポーネントにイベントハンドラを作成すると，自動的にフォームオブジェクトの中にメソッドを作成していることになります。以上のすべては，アプリケーションにユーザーインターフェースを構築し，オブジェクトインスペクタでイベントハンドラを作成する過程で自動的に行われます。このように，開発者が直接関与しない場合もありますが，Delphi でオブジェクトを駆使してアプリケーションを構築する方法を理解することも無駄ではありません。オブジェクトについての詳細は「Delphi オブジェクトを使ったプログラミング」を参照してください。


Understanding Object Pascal units
Understanding Object Pascal units1073069

Section topics	参照

この節では，ユニットの定義，ユニットの使い方，フォームと関連付けられていない独自のユニットの書き方について説明します。


What is a unit?
What is a unit?1073070

Section topics	参照

ユニットとは，複数のアプリケーションで共有できる定数，データ型，変数，手続き，関数の集まりです。Delphi アプリケーションの構築では，多数の定義済みユニットを利用できます。Delphi ビジュアルコンポーネントライブラリは，アプリケーションのインターフェースを設計するためのオブジェクト，コンポーネント，コントロールを宣言する複数のユニットで構成されています。たとえば，フォームにチェックボックスを追加するときは，自動的に StdCtrls ユニットを使用しています。TCheckBox コンポーネントは StdCtrls で宣言されているからです。

アプリケーションのフォームを設計すると，このフォームに関連付けられた新しいユニットが自動的に作成されます。しかし，必ずしもユニットをフォームに関連付ける必要はありません。たとえば，数値演算ルーチンだけの定義済みユニットも使用できます。または，算術関数を集めた独自のユニットを作成することもできます。

ユニット内のすべての宣言は相互に関係しています。たとえば，Dialogs ユニットにはアプリケーションでコモンダイアログボックスを使用するためのすべての宣言が入っています。


The structure of a unit
The structure of a unit1073071

Section topics	参照

フォームと関連付けられているかに関係なく，ユニットの基本構造は同じになります。ユニットの各部は次のとおりです。

unit <identifier>;

interface

uses <ユニットのリスト>;	{省略可能}

{ Public 宣言 }

implementation

uses <ユニットのリスト>;	{省略可能}

{ Private 宣言 }

{ 手続きと関数の実装 }

initialization	{省略可能}

{ オプションの初期化コード }

end;

ユニットのヘッダーは予約語 unit とユニット名 (識別子) で始めます。ユニットの次の項目は予約語 interface であり，ユニットのインターフェース (interface) 部の始まりを示します。interface 部は，このユニットを使用するほかのユニットやアプリケーションから見える部分です。

ユニットでは，uses 節に指定したほかのユニットの宣言も利用できます。uses 節は次の 2 箇所に記述できます。

uses 節を予約語 interface の直後に記述する
現在のユニットのコードでは，現在のユニットの uses 節に指定したほかのユニットの interface 部に宣言された項目を利用できます。
たとえば，ユニット A のコードからユニット B の interface 部に宣言された手続きを呼び出すとします。この場合，ユニット A の interface 部の uses 節にユニット B の名前を追加すれば，ユニット A のコードでユニット B に宣言された手続きを呼び出せます。
ユニット A の interface 部の uses 節にユニット B がある場合，ユニット B の interface 部の uses 節にユニット A を含めることはできません。これはユニットの循環参照になります。循環参照をコンパイルしようとするとエラーメッセージが生成されます。

uses 節を予約語 implementation の直後に記述する
ここに記述したユニットの interface 部の宣言を使用できるのは，現在のユニットだけです。現在のユニットを使用するユニットは，この uses 節にリストされたユニットを使用することはできません。
たとえば，ユニット A の uses 節にユニット B があり，ユニット B の implementation 部の uses 節にユニット C があるとします。この場合，ユニット A ではユニット B の interface 部にある宣言だけを使用できます。ユニット A の uses 節にユニット C がない限り，ユニット A ではユニット C の宣言を使用できません。
ユニット A の implementation 部の uses 節にユニット B がある場合は，ユニット B の implementation 部の uses 節にユニット A を含めることができます。interface 部での循環参照は許されませんが，implementation 部での循環参照は問題ありません。

Interface part1073072

ユニットのインターフェース部は予約語 interface で始めます。interface 部はユニットのヘッダーと予約語 implementation の間に記述します。interface 部では，このユニットを使用するアプリケーションやほかのユニットに見えるもの (アクセスできるもの) を指定します。

ユニットの interface 部では，定数，データ型，変数，手続き，関数を宣言できます。設計したフォームに対して Delphi がユニットを構築した場合，そのユニットの interface 部には，フォームのデータ型，フォームのインスタンスを作成するフォーム変数，イベントハンドラが宣言されます。この宣言についての例は，「イベントハンドラでの作業」を参照してください。

ユニットを使用するほかのユニットやアプリケーションに公開する手続きや関数は，ユニットの interface 部に宣言します。手続きや関数の実際の本体 (実装) はユニットの implementation 部に記述します。この場合 forward 宣言は必要ありません。forward 宣言は interface 部では使用できません。interface 部に，すべての手続きと関数のヘッダーをリストし，implementation 部に，イベントハンドラを含むすべての手続きと関数の実際のコードを記述します。

uses 節を interface 部に記述する場合は，予約語 interface の直後に記述します。

Implementation part1073073

ユニットの実現部は予約語 implementation で始めます。implementation 部のコードは，interface 部に宣言されたすべての項目にアクセスできます。

implementation 部には独自の宣言も追加できます。ただし，これらの宣言はほかのアプリケーションやユニットでは使用できません。このユニット内で宣言された手続き，関数，イベントハンドラでのみ使用できます。

uses 節を implementation 部に記述する場合は，予約語 implementation の直後に挿入します。

interface 部に宣言したルーチンの本体も implementation 部に記述します。implementation 部に記述する手続きや関数のヘッダーは，interface 部に記述した宣言と一致させるか，またはその省略形を使用します。

省略形を使用するには，予約語の procedure または function に続けてルーチン名を入力します。パラメータリストは省略します。関数の場合は，戻り型も省略します。

たとえば，次の関数を interface 部に宣言するとします。

function CalculateInterest(Principal, InterestRate: Double): Double;

implementation 部には，この関数の本体を次のように記述できます。

function CalculateInterest;

begin

  Result := Principal * InterestRate;

end;

この例では，パラメータと戻り値は省略されています。

interface 部ではなく implementation 部にルーチンを宣言する場合は，手続きや関数のヘッダーの省略形は使用できません。

Initialization part1073074

ユニットの使用するデータを初期化するか，ユニットの interface 部をとおしてアプリケーションやほかのユニットにアクセスさせるデータを初期化するには，ユニットに初期化部を追加します。予約語 initialization をユニット最後の予約語 end の直前に記述し，initialization と end の間に，データを初期化するコードを記述します。次に例を示します。

initialization

  { 初期化コードを入れる場所 }

end.

アプリケーションがユニットを使うとき，ユニットの initialization 部のコードが最初に呼び出されます。アプリケーションが複数のユニットを使用している場合は，それぞれのユニットの initialization 部が最初に呼び出されます。initialization 部以外のコードが実行されるのは，その後です。

Finalization part1073075

アプリケーションの終了時にユニットでクリーンアップを実行する必要がある場合は，ユニットに finalization 部を追加します。たとえば，initialization 部で割り当てたリソースを解放する場合などです。finalization 部は initialization 部の後ろで，最後の end の前に入れます。次に例を示します。

initialization

  { 初期化コードを入れる場所 }

finalization

  { 終了処理コードを入れる場所 }

end.

ユニットの初期化と逆に，finalization 部はアプリケーションの終了時の最後に実行されます。


How units are used
How units are used1073076

Section topics	参照

現在のユニットで別のユニットを使用するには，現在のユニットの uses 節に別のユニットの名前を追加します。このユニット名の追加は，設計中のフォームに新しいコンポーネントを追加した場合は自動的に行われます。つまり，Delphi の標準の uses 節にはないユニットの中で宣言されているコンポーネントが追加されると，Delphi はこのユニットの名前を uses 節に追加します。

たとえば，フォームにカラーグリッドを追加すると，ユニットの uses 節の最後に ColorGrd が追加されます。この追加によって，フォームと関連付けられたユニットでは ColorGrd ユニット内のすべての宣言を使用できるようになります。

しかし，ユニットで宣言されたオブジェクトの中には，対応する Delphi のビジュアルコンポーネントを持たないものもあります。たとえば，ユニット内のコードで，定義済みのメッセージボックスを使いたい場合は，ユニットの uses 節に Dialogs ユニットを手作業で追加しなければなりません。また，Printers ユニットの TPrinter オブジェクトを使用する場合なども同様です。

uses 節にユニット名を追加するには次のようにします。

uses 節の末尾のセミコロン (;) の前に，そのユニット名を記述する。このユニット名と先行するユニット名とはカンマ (,) で区切る

ほかのユニットに宣言されているルーチンを使用するには次のようにします。

そのユニットの名前とルーチン名をピリオド (.) で区切って記述する

たとえば，Unit1 に宣言されている関数 ComputerPayment を Unit2 から呼び出す場合は，次のように記述します。

Amount := Unit1.ComputePayment(1000, .085, 242);

ユニット名に続ける識別子は，プロパティ，定数，データ型，変数，ルーチンのいずれかです。

The uses clause in the implementation part1073077

Object Pascal では，ユニットの implementation 部にオプションで uses 節を記述できます。uses 節を記述する場合は，予約語 implementation の直後に挿入します。

implementation 部で uses 節を使うと，ユニットの内部の詳細を隠蔽 (いんぺい) することができます。implementation 部に指定したユニットは，ユニットのユーザーには見えない (アクセスできない) からです。


Writing a unit from scratch
Writing a unit from scratch1073078

Section topics	参照

Delphi が作成するユニットには自由にコードを追加できます。しかし，Delphi が生成したコードは変更しないでください。

フォームと関連付けられていない新しいユニットをプロジェクトで作成する場合は，Delphi の機能を使用します。

新しいユニットを作成するには次のようにします。

［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスの［新規作成］ページで［ユニット］を選択し，［OK］を押す

新しいユニットが現在のプロジェクトに追加されます。新しいユニットのソースコードを次に示します。

unit Unit2;

interface

implementation

end.

ユニットに自動的に付けられる名前は，プロジェクト内の既存のユニット数によって異なります。このスケルトンユニット (ユニットの枠組み) を使って，必要なコードを入力します。

予約語 end と対になる予約語 begin がないことに注意してください。なお，末尾の予約語 end の直前に予約語 initialization を追加して初期化部を作成することもできます。ただし，初期化コードを必要とするユニットを作成することは，そう多くはありません。作成するユニットは，単に関連する手続き，関数，データ型の集合である場合が多いでしょう。初期化コードを追加する場合は，予約語 initialization を挿入し，initialization と end の間に初期化コードを記述します。

プロジェクトをコンパイルまたは構築する場合，追加した新しいユニットは .DCU という拡張子の付いたファイルにコンパイルされます。たとえば，ファイル MYUNIT.PAS をコンパイルすると，MYUNIT.DCU というファイルが作成されます。この新しく作成されたファイルはプロジェクトの実行形式ファイルにリンクされるオブジェクトファイルで，機械語コードを含んでいます。


Adding an existing unit to a project
Adding an existing unit to a project1073079

Section topics	参照

すでに完成しているユニットは，フォームに関連付けられたユニットとして Delphi が作成したものでも，開発者が独自に記述したものでも，プロジェクトに追加するだけで使用できます。

プロジェクトに既存のユニットを追加する方法は，次のとおりです。

1.	ユニットの追加先のプロジェクトを開きます。

2.	［ファイル(F)｜プロジェクトに追加(D)］を選択し，追加するユニットのソースコード (.PAS ファイル) を指定して［OK］を選択します。


See also1073080

例外と実行経路

コードのブロックの保護

オブジェクトのスコープ

Delphi オブジェクトを使ったプログラミング


Programming with Delphi objects
Programming with Delphi objects1070001

Section topics	参照

OOP (オブジェクト指向プログラミング) は，構造化プログラミングから自然に発展したものです。OOP ではよく考えられた論理的なプログラミングが要求され，そのようなプログラミングが簡単にできます。その結果，拡張しやすく管理しやすい整然としたコードを仕上げることができます。

作成したオブジェクトはアプリケーション間で再利用できます。オブジェクトの作成者もほかのプログラマも自由にオブジェクトを再利用でき，大幅な開発時間の短縮と生産性の向上が実現されます。

Delphi と Object Pascal 言語を組み合わせたことで，オブジェクトを利用したプログラミングはいままで以上に簡単になりました。この章では，Delphi を効果的に使いこなすために必要なオブジェクトの基本知識について解説します。新しいコンポーネントを作成して Delphi のコンポーネントパレットに追加する方法については『開発者ガイド』を参照してください。

この章では主に以下の内容について説明します。

オブジェクトとは何か

オブジェクトからのデータとコードの継承

オブジェクトのスコープ

オブジェクト変数への値の代入

非ビジュアルオブジェクトの作成

この章を理解するには，Delphi のツールを使ってアプリケーションのユーザーインターフェースを設計する方法，Delphi プロジェクトを構成する方法，イベントを処理する方法についての知識が必要です。また，Object Pascal 言語の基本知識も必要です。以上についての詳細は，このマニュアルの該当する章を参照するか，Delphi オンラインヘルプを利用してください。


What is an object?
What is an object?1070002

Section topics	参照

オブジェクトは，データとコードをひとまとめにしたデータ型です。OOP の出現までは，コードとデータを別々の要素として扱っていました。

自転車の各部品と組立説明書から自転車を組み立てることを想像してください。オブジェクトを使用せずに Windows プログラムをゼロから記述するのは，この自転車の組み立てに似ています。Delphi を使用すると「自転車の構築」をある程度できあがったところから始められます。「自転車の組み立て済み部品」に相当する Delphi のフォームとコンポーネントが多数用意されているからです。

Object Pascal のレコードを理解すると，Object Pascal のオブジェクトを理解するのが簡単になります。「Object Pascal コードの書き方」では，レコードはフィールドで構成されていること，各フィールドはデータを含み，独自のデータ型を持つことを解説しました。レコードを使用すると，関連するさまざまなデータ要素の集合を一括して簡単に取り扱えます。

オブジェクトもデータ要素の集合であり，独自のデータ型を持つフィールドで構成されています。この点はレコードと同じです。

しかし，オブジェクトにはフィールド内のデータに作用するコード (手続きと関数) も含まれています。この点はレコードと異なります。このような手続きや関数をメソッドと呼びます。

さらに，オブジェクトにはプロパティもあります。この点もレコードと異なります。Delphi のオブジェクトのプロパティにはデフォルト値が設定されています。デフォルト値を設計時に変更すると，コードを記述しなくてもプロジェクトのニーズに応じてオブジェクトを変更できます。ただし，わずかなコードを記述するだけで，プロパティ値を実行時に変更することもできます。


Examining a Delphi object
Examining a Delphi object1070003

Section topics	参照

新規プロジェクトを作成すると，Delphi は新規フォームを表示してカスタマイズできるようにします。コードエディタには，このフォームの新しいオブジェクト型が宣言され，新規フォームオブジェクトを作成するコードが生成されます。新規フォームのそれぞれに新しいオブジェクト型を宣言する理由は，後の節で説明します。とりあえずここでは，コードエディタのコードの例を示します。

unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Apps;

type

  TForm1 = class(TForm)	{フォームの型宣言の始まり}

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;	{フォームの型宣言の終わり}

var

  Form1: TForm1;

implementation	{実現部の始まり}

{$R *.DFM}

end.	{実現部とユニットの終わり}

上の例では，新しいオブジェクト型 TForm1 を別のオブジェクト型である TForm から派生させています。なお，TForm と他のオブジェクトからの派生オブジェクトについては，後の節で詳しく解説します。

オブジェクトはデータフィールドを持つという点でレコードと共通していますが，メソッドも持つという点でレコードとは異なることを指摘しました。メソッドはオブジェクトのデータに作用するコードです。しかし，上の例で TForm1 にはデータフィールドもメソッドも示されていません。この理由は，フォームにコンポーネント (新しいオブジェクトのフィールド) やイベントハンドラ (新しいオブジェクトのメソッド) を作成していないことによります。なお，後に述べるように，型宣言に示されなくても TForm1 にはデータフィールドもメソッドもあります。

次の変数宣言では，新しいオブジェクト型 TForm1 の変数として Form1 を宣言します。

This variable declaration declares a variable named Form1 of the new object type TForm1.

var

  Form1: TForm1;

Form1 を TForm1 型のインスタンスと呼びます。この変数 Form1 で参照されるフォームにコンポーネントを追加して，ユーザーインターフェースを設計します。

同じオブジェクト型の複数のインスタンスを宣言することもできます。たとえば，MDI (マルチドキュメントインターフェース) アプリケーションで複数の子ウィンドウを管理する場合などです。この場合，インスタンスごとに独自のパッケージに独自のデータを持ちますが，すべてのオブジェクトのインスタンスは共通のコードを使用します。

コンポーネントの追加もコードの記述も行っていないフォームであっても，独立した Delphi アプリケーションとしてコンパイル，実行できます。ただ，データフィールドもメソッドもないため，空のフォームを表示するだけのアプリケーションになります。

では，このフォームにボタンコンポーネントとボタンの OnClick イベントハンドラを追加し，ユーザーがボタンをクリックしたときにフォームの色を変更するとします。非常に初歩的ですが実際に動作するアプリケーションになりました。このアプリケーションのフォームを次に示します。

ユーザーがボタンをクリックするとフォームの色は緑色に変わります。このボタンの OnClick イベントハンドラのコードは次のとおりです。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Form1.Color := clGreen;

end;

このアプリケーションを作成してコードエディタを開くと，コードは次のように表示されます。

unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Apps;

type

  TForm1 = class(TForm)

    Button1: TButton;	TButton;	{新しいデータフィールド}

    procedure Button1Click(Sender: TObject);	{新しいメソッドの宣言}

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;

var

  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);	{新しいメソッドのコード}

begin

  Form1.Color := clGreen;

end;

end.

新しいオブジェクト型 TForm1 には，フォームに追加したボタンを示すフィールド Button1 が挿入されています。Tbutton はオブジェクト型なので，Button1 もオブジェクトです。TForm1 に Button1 を挿入できるのは，オブジェクト型に別のオブジェクトをデータフィールドとして挿入できるからです。フォームに追加する新しいコンポーネントごとに，コンポーネントと同じ名前の新しいフィールドがフォームの型宣言に挿入されます。

Delphi で記述するすべてのイベントハンドラは，フォームオブジェクトのメソッドです。イベントハンドラを作成するごとに，フォームオブジェクト型ではメソッドが宣言されます。TForm1 の型宣言では，TForm1 型の新しいメソッドとして手続き Button1Click が宣言されています。

Button1Click メソッドの実際のコードは，ユニットの implementation 部に挿入されています。このメソッドは，Delphi が作成した空のイベントハンドラに，アプリケーション実行時にユーザーがボタンをクリックすると応答するようなコードを埋め込んだものです。

Changing the name of a component1070004

コンポーネントの名前を変更するには，必ずオブジェクトインスペクタを使用します。たとえば，フォームのデフォルト名を Form1 から別の名前に変更するには，オブジェクトインスペクタで Name プロパティの値を変更します。この変更は Delphi で生成したコード全体に反映されます。先のアプリケーションのフォームの名前を ColorBox に変更した場合，コードは次のようになります。

unit Unit1;

interface

uses Windows, Classes, Graphics, Forms, Controls, Apps;

type

  TColorBox = class(TForm)	{TForm1 から TColorBox に変わった}

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;

var

  ColorBox: TColorBox;	{Form1 から ColorBox に変わった}

implementation

{$R *.DFM}

procedure TColorBox.Button1Click(Sender: TObject);

begin

  Form1.Color := clGreen;	{Form1 への参照は変わっていない！}

end;

end.

フォームオブジェクト型の名前は TForm1 から TColorBox に変わりました。また，フォーム変数も新しいフォーム名 ColorBox に変わりました。最後の begin..end ブロックはフォームオブジェクトを作成してアプリケーションを実行するコードですが，このブロックにも ColorBox 変数と TColorBox 型への参照が示されています。このように，最初から Delphi が生成したコードは，オブジェクトインスペクタでフォームなどのコンポーネントの名前を変更すると，コードはそれに合わせて自動的に更新されます。

しかし，ボタンの OnClick イベントハンドラに記述したコードは変わっていません。これはコードを手作業で記述したためです。フォームの名前を変更した場合，手作業で記述したコードは手作業で更新しなければなりません。つまり，この例ではフォームへの参照を手作業で訂正しなければなりません。この変更を行わないとコードはコンパイルできません。上の例では，コードを次のように変更します。

procedure TColorBox.Button1Click(Sender: TObject);

begin

  ColorBox.Color := clGreen;

end;

オブジェクトインスペクタを使用した場合だけコンポーネントの名前を変更できます。Delphi の生成したコードの変更やコンポーネント変数の名前は変更できますが，プログラムをコンパイルすることはできません。


Inheriting data and code from an object
Inheriting data and code from an object1070005

Section topics	参照

「Delphi のオブジェクトの概要」に示したオブジェクト TForm1 は単純そのものに見えます。このアプリケーションを作成すると，TForm1 には 1 つのデータフィールド Button1 と 1 つのメソッド Button1Click だけが示され，プロパティは示されません。ところが，このアプリケーションでは，フォームのサイズ変更，最大表示ボタンやアイコン化ボタンの追加または削除，MDI アプリケーションに組み込むためのフォームの設定などが可能です。1 つのフィールドと 1 つのメソッドしかないフォームで，なぜこれだけのことができるのでしょうか。

この理由は継承にあります。自転車の例を思い出してください。すべてのオブジェクトを一体化した「自転車オブジェクト」は乗り回すことができます。一体化した自転車では，ペダルを踏んで車輪を回し，サドルに体を乗せ，ハンドルで進路を決めることができます。つまり，自転車としての基本機能を完備しています。同じように，プロジェクトに追加した新しいフォームには，フォームとしてのすべての機能が与えられています。たとえば，ほかのコンポーネントを挿入するスペースや，フォーム自体の開閉，表示，非表示などを行うメソッドがすべてのフォームに与えられます。

では，次に自転車を改造する場合を考えます。自転車を改造するのは，Delphi でフォームオブジェクトをカスタマイズするのと同じです。自転車の改造では，ギヤを増やしたり，ヘッドライトを付けたり，ベルの音を変えたりします。同じように，フォームをカスタマイズするには，ボタンの追加や位置の変更を行ったり，プロパティ値を変更したり，フォームに格子縞の背景を表示するメソッドを追加したりします。

自転車を改造する出発点は基本モデルであり，この基本モデルに手を加えて改造します。Delphi のフォームをカスタマイズする場合も同じです。プロジェクトに新しいフォームを追加することは基本モデルのフォームを作成することに相当します。この新しいフォームに対してコンポーネントを追加したり，プロパティ値を変更したり，イベントハンドラを記述することによってカスタマイズします。

オブジェクトの種類は，空白フォーム，ダイアログボックスのように使われる複数のコントロールを持つフォーム，Delphi ビットマップボタンの新バージョンなど，さまざまです。どのオブジェクトをカスタマイズする場合でも，最初に既存のオブジェクトから新しいオブジェクトを派生させます。プロジェクトに新しいフォームを追加すると，Delphi は自動的に TForm 型から新しいフォームオブジェクトを派生させます。

新しいフォームをプロジェクトに追加したばかりの時点では，新しいフォームオブジェクトは TForm 型と一致しています。このフォームに対してコンポーネントを追加したり，プロパティを変更したり，イベントハンドラを記述すると，新しいフォームオブジェクトと TForm 型は一致しなくなります。

改造自転車でも自転車の基本機能は前と同じです。同じように，カスタマイズしたフォームオブジェクトもフォームに組み込まれたすべての機能は元のとおりです。つまり，色を変更したり，サイズを変更したり，閉じたりする基本機能に変わりはありません。新しいフォームオブジェクトには TForm 型からすべてのデータフィールド，プロパティ，メソッド，イベントが継承されるからです。

新しいフォームを Delphi プロジェクトに追加すると，Delphi はより汎用的なオブジェクトから派生させた新しいオブジェクト型 TForm1 を作成します。TForm1 を TForm から派生させる指定は，TForm1 型宣言の最初の行で行います。

TForm1 = class(TForm)

TForm から派生させた TForm1 には，TForm 型に属するすべての要素が自動的に継承されます。フォーム自体をクリックしてから〔F1〕キーを押し，オンラインヘルプで TForm を調べてみてください。TForm オブジェクト型のすべてのプロパティ，メソッド，イベントのリストが表示されます。アプリケーションでは TForm から継承したすべての要素を使用できます。ただし，TForm1 の型宣言には TForm1 型に新しく追加した要素だけが示されます。つまり，フォームに追加したコンポーネントやイベントに応答して記述したイベントハンドラ (メソッド) などが示されます。このように新しく追加した分だけ，TForm と TForm1 の間には差異が生じます。

カスタマイズしたオブジェクトのデータとコードの継承元である汎用オブジェクトを，カスタマイズしたオブジェクトの上位オブジェクトと呼びます。上位オブジェクトに対して，カスタマイズしたオブジェクトを下位オブジェクトと呼びます。オブジェクトは直接の上位オブジェクトを 1 つしか持てませんが，複数の下位オブジェクトを持つことができます。たとえば，TForm は TForm1 の上位オブジェクト型であり，TForm1 は TForm の下位オブジェクト型です。すべてのフォームオブジェクトは TForm の下位オブジェクトであり，TForm からは複数のオブジェクトを派生できます。


Objects, components, and controls
Objects, components, and controls1070006

Section topics	参照

オンラインヘルプで TForm を検索するとわかりますが，オンラインヘルプでは TForm をコンポーネントと呼んでいます。少し混乱しそうですが，すべてのコンポーネントやコントロールもオブジェクトです。オンラインヘルプで TForm をコンポーネントと呼ぶのは，Delphi ビジュアルコンポーネントライブラリの継承階層に基づいています。

大きく簡略化した継承の階層図を示します。この図では中間のオブジェクトをすべて省略しています。1070007

この階層に示されたものはすべてオブジェクトです。コンポーネントは TObject 型からデータとコードを継承するオブジェクトです。コンポーネントは，継承したデータとコードに適切なプロパティ，メソッド，イベントを追加することで特殊化できます。たとえば，コンポーネントの状態をファイルに保存する機能を追加することができます。コントロールは，(TObject 型から要素を継承した) TComponent 型からデータとコードを継承するオブジェクトです。コントロールには表示機能などの機能が追加され，より特殊化されています。コントロールはコンポーネントでありオブジェクトでもあります。しかし，コンポーネントはオブジェクトですがコントロールであるとは限らず，オブジェクトは単にオブジェクトです。この章では，すべてのコンポーネントとコントロールをオブジェクトと呼ぶことがあります。

TCheckBox は TObject の直接の下位オブジェクトではありませんが，オブジェクトのすべての属性を備えています。VCL 階層において，TCheckBox の最終的な派生元は TObject だからです。TCheckBox は，TObject，TComponent，TControl のすべての機能を継承し，さらに独自の機能も持った特殊化されたオブジェクトです。


Object scope
Object scope1070008

Section topics	参照

オブジェクトのスコープは，オブジェクト内のデータフィールド，プロパティ，メソッドの有効性，アクセス可能性を決定します。前の自転車の例に戻ると，カスタマイズした「自転車オブジェクト」だけにヘッドライトを付けた場合，このヘッドライトはカスタマイズした自転車だけのものであり，ほかの自転車には属しません。しかし，「基本モデルの自転車オブジェクト」にヘッドライトを含めると，すべての自転車オブジェクトがヘッドライトの存在を継承します。つまり，上位オブジェクトのスコープ内に入れたヘッドライトは，すべての下位自転車オブジェクトに継承させることができます。これに対して，カスタマイズした自転車オブジェクトのスコープ内に入れたヘッドライトは，ほかの自転車からは利用できません。

同じように，あるオブジェクトで宣言したすべてのデータフィールド，プロパティ，メソッドはこのオブジェクトのスコープ内に存在し，このオブジェクトとすべての下位オブジェクトで使用できます。メソッドを構成するコードはユニットの implementation 部にあり，オブジェクト宣言内にはありません。しかし，メソッドの宣言はオブジェクト宣言内にあるので，やはりメソッドもオブジェクトのスコープ内にあります。

オブジェクトのイベントハンドラにコードを書くとき，そのオブジェクト自身のプロパティ，メソッド，フィールドを参照する場合は，各識別子の前にオブジェクト変数の名前を指定しなくてもかまいません。たとえば，新しいフォームに 1 つのボタンと 1 つの編集ボックスを挿入したとすると，このボタンの OnClick イベントのイベントハンドラを次のように記述できます。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Color := clFuchsia;

  Edit1.Color := clLime;

end;

最初の文では，フォームに色を付けます。この文は次のようにも記述できます。

Form1.Color := clFuchsia

Color プロパティの前の限定子 Form1 は，必ずしも必要ではありません。Button1Click メソッドは TForm1 オブジェクトのスコープ内にあるからです。オブジェクトのスコープ内で使用する限り，このオブジェクトのプロパティ，メソッド，フィールドに限定子を付加する必要はありません。

2 番目の文では，TEdit オブジェクトの Color プロパティを参照します。使用するのは TForm1 型ではなく TEdit1 型の Color プロパティです。したがって，正しい Color プロパティをコンパイラに選択させるために，編集ボックスの名前を付加して Color プロパティのスコープを指定します。編集ボックスの名前を付けないと，2 番目の文は最初の文と同じように解釈されます。つまり，このイベントハンドラを実行すると，フォームの色がライムグリーンになり，編集ボックスコントロールの色は変更されません。

Color プロパティを変更する編集ボックスの名前を指定するのに，なぜフォームの名前を付けないのかと不思議に思われるかもしれません。フォームの名前を指定しない理由は，コントロール Edit1 が TForm1 オブジェクトのスコープ内にあるからです。つまり，Edit1 が TForm1 のデータフィールドとして宣言されているからです。


Accessing components on another form
Accessing components on another form1070009

Section topics	参照

Edit1 がほかのフォームにある場合は，編集ボックス名の前にフォームオブジェクト変数の名前を付加します。たとえば Edit1 が Form2 にある場合，Edit1 は TForm2 オブジェクト宣言の中のデータフィールドであり，Form2 のスコープ内にあります。TForm1.ButtonClick メソッドで Form2 の編集ボックスの色を変更する文を次に示します。

Form2.Edit1.Color := clLime;

ほかのフォームにあるコンポーネントのメソッドにも同じ方法でアクセスできます。次に例を示します。

Form2.Edit1.Clear;

Form1 のコードで Form2 のプロパティ，メソッド，イベントにアクセスするには，Unit1 の uses 節に Unit2 を追加します。ただしこれは，Form1 と Form2 に関連付けられたユニットがそれぞれ Unit1 と Unit2 である場合です。uses 節についての詳細は，「Object Pascal のユニット」を参照してください。


Scope and descendants of an object
Scope and descendants of an object1070010

Section topics	参照

オブジェクトのスコープは，オブジェクトのすべての下位オブジェクトに及びます。つまり，TForm に属するすべてのデータフィールド，プロパティ，メソッド，イベントは TForm1 のスコープ内にあります。TForm1 は TForm の下位オブジェクトだからです。なお，アプリケーションではデータフィールドを上位オブジェクトのデータフィールドと同じ名前で宣言することはできません。

識別子が重複しているというメッセージが表示された場合は，同じ名前のデータフィールドが TForm などの上位オブジェクトに存在する可能性があります。このメッセージが表示された理由がわからない場合は，識別子の名前を少し変更してみてください。上位オブジェクトのデータフィールドと同じ名前を使ってしまうということはあり得ることです。

Overriding a method1070011

上位オブジェクト内のメソッドの名前で下位オブジェクト内のメソッドを宣言することはできます。これをメソッドのオーバーライドと呼びます。既存のメソッドをオーバーライドすれば，上位オブジェクトのメソッドと同じ処理を，別の方法で下位オブジェクトのメソッドに行わせることができます。この場合，この 2 つのメソッドを実現するコードは異なります。

新しいコンポーネントを作成しない限り，メソッドをオーバーライドすることはまずありません。しかし，オーバーライドできるということ，つまりオーバーライドしてもコンパイラは警告やエラーメッセージを出力しないということは覚えておいてください。メソッドのオーバーライドについての詳細は『開発者ガイド』を参照してください。


Public and private declarations
Public and private declarations1070012

Section topics	参照

Delphi の環境を使ってアプリケーションを構築すると，TForm の下位オブジェクトにデータフィールドとメソッドを自動的に追加することになります。しかし，オブジェクトにデータフィールドとメソッドを追加する方法は，フォームにコンポーネントを追加したりイベントハンドラにコードを記述するだけではありません。オブジェクトの型宣言を直接変更する方法もあります。

オブジェクトの public 部または private 部には新しいデータフィールドやメソッドを追加できます。public と private は Object Pascal 言語の標準指令です。標準指令は予約語と同じように考えてください。プロジェクトに新しいフォームを追加すると，Delphi は新しいフォームオブジェクトの構築を始めます。新しいオブジェクトには，コードにデータフィールドやメソッドを直接追加する場合の位置を示す public 指令と private 指令があります。たとえば，次の新しいフォームオブジェクトの宣言にはデータフィールドもメソッドもありませんが，private 部と public 部があります。

type

  TForm1 = class(TForm)

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;

public 部の使い方は以下のとおりです。

ほかのユニットに属するオブジェクトのメソッドからアクセスさせるデータフィールドを宣言する

ほかのユニットのオブジェクトからアクセスさせるメソッドを宣言する

private 部の宣言にはアクセス制限があります。private として宣言したフィールドやメソッドは，オブジェクトの定義されているユニット外からは認識されず，アクセスできません。private 部の使い方は以下のとおりです。

現在のユニットのメソッドだけにアクセスさせるデータフィールドを宣言する

現在のユニットに定義されているオブジェクトだけにアクセスさせるメソッドを宣言する

public 部や private 部にデータフィールドやメソッドを追加するには，それぞれのコメントの後にそれらの宣言を記述します。コメント自体は削除してもかまいません。

type

  TForm1 = class(TForm)

    Edit1: TEdit;

    Button1: TButton;

    procedure Button1Click(Sender: TObject);

  private

    { Private 宣言 }

    Number: Integer;

    function Calculate(X, Y: Integer): Integer;

  public

    { Public 宣言 }

    procedure ChangeColor;

  end;

Calculate メソッドと ChangeColor メソッドを実装するコードはユニットの implementation 部に入れます。

Number データフィールドと Calculate 関数は private として宣言されています。したがって，Number と Calculate を使用できるのは，このユニット内のオブジェクトだけです。通常これは，フォームオブジェクトだけが使用できる，ということになります。多くの場合，Delphi の各ユニットにはオブジェクト型宣言が TForm 型 1 つしかないからです。

ChangeColor メソッドは public として宣言されているので，ほかのユニットのコードでも使用できます。なお，ほかのユニットからのメソッド呼び出しには，次のように必ずオブジェクト名を指定します。

Form1.ChangeColor;

また，このメソッドを呼び出すユニットの uses 節には，必ず Form1 を追加します。

メモ	オブジェクトの public 部や private 部にデータフィールドやメソッドを追加する場合は，必ずデータフィールドの後にメソッド宣言を置いてください。


Accessing object fields and methods
Accessing object fields and methods1070013

Section topics	参照

フォームオブジェクトのフィールドになっているオブジェクトのプロパティ値を変更したり，メソッドを呼び出す場合は，このオブジェクトの名前を必ずプロパティ名やメソッド名に含めます。たとえば，フォームに編集ボックスコントロールがあるとします。このコントロールの Text プロパティの値を変更する場合は，編集ボックスの名前 (この例では Edit1) を必ず指定して，次のような代入文を記述します。

Edit1.Text := 'Frank Borland was here';

同じように，編集ボックスコントロールで選択されているテキストをクリアするには，ClearSelection メソッドへの呼び出しを次のように記述します。

Edit1.ClearSelection;

フォームオブジェクトのフィールドになっているオブジェクトがあり，このオブジェクトの複数のプロパティ値を変更したり，複数のメソッドを呼び出す場合は，with 文を使用してコードを簡略化できます。with 文をオブジェクトで使用するのは，レコードで使用するのと同じように簡単です。たとえば，フォームでユーザーがボタンをクリックしたときに，リストボックスに複数の変更を行うイベントハンドラを次に示します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  ListBox1.Clear;

  ListBox1.MultiSelect := True;

  ListBox1.Items.Add('One');

  ListBox1.Items.Add('Two');

  ListBox1.Items.Add('Three');

  ListBox1.Sorted := True;

  ListBox1.Font.Style := [fsBold];

  ListBox1.Font.Color := clPurple;

  ListBox1.Font.Name := 'Times New Roman';

  ListBox1.ScaleBy(125, 100);

end;

with 文を使用した場合，このコードは次のようになります。

procedure TForm1.Button1Click(Sender: TObject);

begin

  with ListBox1 do

  begin

    Clear;

    MultiSelect := True;

    Items.Add('One');

    Items.Add('Two');

    Items.Add('Three');

    Sorted := True;

    Font.Style := [fsBold];

    Font.Color := clPurple;

    Font.Name := 'Times New Roman';

    ScaleBy(125, 100);

  end;

end;

with 文を使用すると，ListBox1 の各プロパティや各メソッドへの参照を限定するためにいちいち ListBox1 識別子を付加しなくて済むようになります。with 文内では，呼び出されたすべてのプロパティやメソッドは ListBox1 オブジェクト変数のローカルスコープとなります。


Assigning values to object variables
Assigning values to object variables1070014

Section topics	参照

オブジェクト変数は，同じ型か代入互換性のある型の別のオブジェクト変数に代入できます。これは，オブジェクト以外の型の変数が，同じ型か代入互換性のある型のほかの変数に代入できるのと同じです。たとえば，TForm 型から派生したオブジェクトの TForm1 と TForm2 で変数の Form1 と Form2 を宣言している場合，Form1 を Form2 に代入できます。

Form2 := Form1;

値を代入するオブジェクト変数の型が，上位と下位の関係にある場合も，代入先が上位であれば代入できます。たとえば，次のような TDataForm 型宣言と変数宣言部があるとします。変数宣言部には AForm と DataForm の 2 つの変数が宣言されています。

type

  TDataForm = class(TForm)

    Button1: TButton;

    Edit1: TEdit;

    DataGrid1: TDataGrid;

    Database1: TDatabase;

  private

    { Private 宣言 }

  public

    { Public 宣言 }

  end;

var

  AForm: TForm;

  DataForm: TDataForm;

AForm は TForm 型に属し，DataForm は TDataForm 型に属します。TDataForm は TForm の下位オブジェクトなので次の代入文は正しいものです。

AForm := DataForm;

なぜこんなことが重要なのかと思われるかもしれません。しかし，アプリケーションでイベントハンドラを呼び出したとき実際にどのような処理が行われるのかを考えれば，理由がわかります。

ボタンの OnClick イベントのイベントハンドラを記述したとします。ボタンをクリックすると，この OnClick のイベントハンドラが呼び出されます。

どのイベントハンドラにも TObject 型の Sender パラメータがあります。たとえば，次の空の Button1Click ハンドラの Sender パラメータに注意してください。

procedure TForm1.Button1Click(Sender: TObject);

begin

end;

「オブジェクト，コンポーネント，コントロール」の図「簡略化した階層図」に戻って確認すると，TObject は Delphi ビジュアルコンポーネントライブラリの最上位にあります。つまり，すべての Delphi オブジェクトは TObject の下位オブジェクトであり，TObject 型に属する Sender にはあらゆるオブジェクトを代入できることになります。代入を示すコードは表示されませんが，Sender にはイベントに応答するコンポーネントやコントロールが代入されます。すなわち，Sender の値は常に発生したイベントに応答するコントロールやコンポーネントを指しているのです。

この情報は非常に役に立ちます。予約語 is を使用して Sender を調べると，イベントハンドラを呼び出したコンポーネントやコントロールの型がわかります。次に例を示します。

if Sender is TEdit then

  DoSomething

else

  DoSomethingElse;

Demos\Dragdrop ディレクトリにはドラッグアンドドロップを行うデモプロジェクトとして，DRAGDROP.DPR というプロジェクトファイルが添付されています。このプロジェクトを読み込んで DROPFONT.PAS ユニットコードを調べると，Memo1DragOver メソッドではオブジェクト変数の型をチェックしていることがわかります。次の場合，パラメータは Sender ではなく Source です。

procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;

  State: TDragState; var Accept: Boolean);

begin

  Accept := Source is TLabel;

end;

Source パラメータも TObject 型に属します。Source にはドラッグされるオブジェクトが代入されます。Memo1DragOver メソッドの目的はラベルだけをドラッグさせることです。Accept は論理パラメータなので，True と False のどちらかの値を取ります。Accept が True であれば，ユーザーの選択したコントロールはドラッグできます。Accept が False であれば，ユーザーの選択したコントロールはドラッグできません。

Accept 変数に次の式が代入されます。

Source is TLabel

予約語 is は Source 変数をチェックして Source が TLabel 型かどうかを判定します。Source が TLabel 型であれば式を True と評価します。式が True になるのはユーザーがラベルをドラッグしようとしたときだけなので，Accept も同じ条件で True を返すようにします。

ドラッグアンドドロップデモでは，次のイベントハンドラ Memo1DragDrop も Source パラメータを使っています。このメソッドの目的は，メモコントロールのテキストのフォントを，メモコントロールにドロップされたラベルのフォントに変更することです。このメソッドの実装を次に示します。

procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);

begin

  Memo1.Font := (Source as TLabel).Font;

end;

このハンドラの代入文を記述した時点では，開発者にはユーザーがドラッグするラベルの名前がわかりません。そこで，ラベルの名前を (Source as TLabel) として参照することによって，ユーザーのドロップしたラベルのフォントを Memo1.Font に代入します。Source にはユーザーのドラッグアンドドロップしたコントロールの名前が入っているからです。Source がラベルの場合にだけイベントハンドラでは代入が行われます。


Creating nonvisual objects
Creating nonvisual objects1070015

Section topics	参照

編集ボックスや文字列グリッドなど，Delphi で使用する大半のオブジェクトは設計時と実行時の両方に表示されます。しかし，コモンダイアログボックスなどのいくつかのオブジェクトは，実行時にだけ表示されて設計時には表示されないコンポーネントです。また，タイマーやデータソースコンポーネントなど，実行時のビジュアルな表現手段をいっさい持たないけれどもアプリケーションで使用されているオブジェクトもあります。

アプリケーションで使用する非ビジュアルオブジェクトを独自に作成する場合もあります。たとえば，Name，Title，HourlyPayRate の各フィールドを含む TEmployee オブジェクトを作成するとします。さらに，HourlyPayRate フィールドのデータを使用する CalculatePayAmount メソッドを追加して，ある期間の給与額を計算します。

TEmployee 型は次のように宣言できます。

type

  TEmployee = class(TObject)

    Name: string[25];

    Title: string[25];

    HourlyRate: Double;

    function CalculatePayAmount: Double;

  end;

この例で TEmployee は TObject から派生しています。TEmployee には 3 つのデータフィールドと 1 つのメソッドがあります。TEmployee は TObject から派生しているので，TObject のすべてのメソッドを使用できます。なお，TObject にデータフィールドはありません。

Delphi の助けを借りずに作成したオブジェクト型宣言を，フォーム型宣言とともにユニットの型宣言部に挿入します。

ユニットの変数宣言部には新しい型の変数を宣言します。

var

  Employee: TEmployee;


Creating an instance of an object
Creating an instance of an object1070016

Section topics	参照

TEmployee は単なるオブジェクト型です。実際のオブジェクトは，コンストラクタを呼び出して作成 (またはインスタンス化) するまではメモリ内に存在しません。コンストラクタは，新しいオブジェクトにメモリを割り当てて新しいオブジェクトを指すポインタを返すメソッドです。メモリを割り当てた新しいオブジェクトを，オブジェクト型のインスタンスと呼びます。Create メソッドつまりコンストラクタを呼び出して，このインスタンスを変数に代入します。

TEmployee 型のインスタンスを宣言する場合，先に Create を呼び出してからオブジェクトのフィールドにアクセスします。

Employee := TEmployee.Create;

TEmployee 型宣言に Create メソッドはありません。しかし，TEmployee の派生元である TObject に Create メソッドがあります。したがって，TEmployee でも Create を呼び出して TEmployee のインスタンスを作成し，このインスタンスを Employee 変数に代入できます。

この後は，ほかの Delphi オブジェクトにアクセスする場合と同じように，Employee オブジェクトのフィールドにアクセスできます。


Destroying your object
Destroying your object1070017

Section topics	参照

使い終わったオブジェクトは廃棄し，オブジェクトの使用していたメモリを解放します。オブジェクトを廃棄するにはデストラクタを呼び出します。デストラクタは，オブジェクトに割り当てたメモリを解放するメソッドです。

Delphi では Destroy と Free の 2 つのデストラクタを使用できます。できれば常に Free を使用します。Free メソッドはインスタンスポインタが nil でない場合にだけ Destroy メソッドを呼び出します。つまり，ポインタがインスタンスを指している場合だけです。このため，Free を呼び出す方が Destroy を呼び出すよりも安全です。さらに，Free を呼び出す方が少しだけコードサイズを節約できます。

使い終わった Employee オブジェクトを廃棄するには，次の呼び出しを行います。

Employee.Free;

TEmployee は TObject から，Create メソッドと同様に Free メソッドも継承しています。

より厳密なプログラミングを行うのであれば，デストラクタの呼び出しは try..finally ブロックの finally 部に，オブジェクトを使用するコードは try 部に置きます。こうすると，コードでオブジェクトを使用中に例外が発生した場合も，オブジェクトに割り当てたメモリを解放できます。例外と try..finally ブロックについての詳細は，「例外の処理」を参照してください。

非ビジュアルオブジェクトの一般的な作成例については，「文字列リストの操作」を参照してください。Delphi アプリケーションでは文字列リストのオブジェクトはよく使います。


See also1070018

コンポーネントの概要

コンポーネントの作成の概要

コードエディタの使い方


Using the integrated debugger
Using the integrated debugger1058001

Section topics	参照

作成したばかりのプログラムは，どれほど注意してコードを記述したとしても，エラー，つまりバグが付きもので，設計のとおりには動作しないものです。このようなプログラムのエラーを探して修正する工程をデバッグといいます。

Delphi は統合デバッガを用意しているので，Delphi 統合開発環境を離れずにプログラムをデバッグできます。この章では以下の内容について説明します。

バグの種類

デバッグの計画

デバッグセッションの開始

プログラム実行の制御

プログラムの再起動

ブレークポイントの使い方

プログラムのデータ値の調査

関数呼び出しの表示

ハードウェア例外と言語例外の処理

統合デバッガにアクセスするには，［実行(R)］メニューと［表示(V)］メニューのどちらかを使用します。


Types of bugs
Types of bugs1058002

Section topics	参照

統合デバッガでは，実行時エラーと論理エラーの 2 種類の基本的なプログラミングエラーを簡単に発見できます。


Runtime errors
Runtime errors1058003

Section topics	参照

プログラムのコンパイルに成功しても，実行中にエラーが発生することがあります。このようなエラーを実行時エラーと呼びます。つまり，プログラムの 1 文 1 文は正しいのに，実行するとエラーを起こすわけです。たとえば，存在しないファイルを開こうとした場合や，数値を 0 で除算した場合などがあります。オペレーティングシステムがこのような実行時エラーを探知すると，プログラムの実行は中止されます。

実行時エラーはデバッガなしでは探しにくいものです。コンパイラによってソースコード上のエラー箇所が通知されることはないからです。たいていは，プログラムが問題を起こした場所と実行時エラーが生成したエラーメッセージだけを手がかりに作業しなければなりません。

プログラムのソースコードを丹念に探して実行時エラーを発見することも不可能ではありませんが，統合デバッガを使えば，エラーをより簡単に見つけられます。たとえば，統合デバッガではプログラムの特定箇所に移行できます。さらに移行先から文単位でプログラムを実行し，文単位でプログラムの動作を調べることができます。プログラムが問題を起こす文にたどり着けば，そこがエラーの発生箇所です。そのソースコードを修正し，プログラムを再コンパイルし，プログラムのテストを再開します。


Logic errors
Logic errors1058004

Section topics	参照

論理エラーとは，プログラムの設計上，実装上のエラーです。つまり，プログラムの文は正しくて問題なく動作しても，その動作がコード作成時の意図とは異なる場合です。たとえば，変数に不正な値があるか，グラフィックイメージが正しく表示されないか，プログラムの出力が不正であるというようなエラーは，論理エラーと呼ばれます。

論理エラーは意外な箇所に発生することがあるので，実行時エラーよりも発見しにくいものです。プログラムを設計どおりに動作させるには，多方面から徹底したテストをしなければなりません。プログラムを設計のとおりに動作させるには，プログラムのユーザーインターフェースと出力の各部分を丹念に調べる以外に方法はありません。しかし，統合デバッガを使えば，実行時エラーと同じように論理エラーも簡単に発見できます。統合デバッガでは，プログラムを実行しながらプログラム変数とデータオブジェクトの値を監視できます。


Planning a debugging strategy
Planning a debugging strategy1058005

Section topics	参照

プログラムの設計後は，コード記述とデバッグのサイクルを繰り返しながらプログラムの開発を進めます。プログラムは徹底的にテストしてからエンドユーザーに配布します。プログラムを各方面からテストするには，デバッグサイクルの綿密な計画を作成するのが一番です。

デバッグ方法として有効な方法の 1 つは，プログラムをセクション単位に分割して計画的にデバッグすることです。セクション単位で文を詳細に監視することで，各セクションが設計のとおりに動作することを確認します。プログラミングエラーを発見したときは，ソースコードでエラーを修正し，プログラムを再コンパイルし，再びテストを行います。


Starting a debugging session
Starting a debugging session1058006

Section topics	参照

プログラムの実行時エラーや論理エラーを発見したら，デバッガの制御の下でプログラムを実行して，デバッグセッションを開始します。

デバッグセッションを開始する方法は次のとおりです。

1.	プログラムをコンパイルするときにデバッグ情報を生成します。

2.	Delphi の統合環境からプログラムを起動します。

デバッグ中はプログラムの実行を完全に制御できます。たとえば，プログラムを必要な場所で一時停止し，変数の値やデータ構造を調べたり，関数の呼び出し履歴を表示したり，変数の値をさまざまに変更してプログラムの動作の変化を確認できます。

またデバッガでは，プログラムの実行をステップ単位で監視することもできます。プログラムのソースコードをステップ単位で実行することで，プログラムを監視しながら実行することができます。詳しくは「トレース実行とステップ実行」を参照してください。


Generating debugging information
Generating debugging information1058007

Section topics	参照

デバッグセッションを開始する前に，プロジェクトのコンパイル時にシンボリックデバッグ情報を生成しておきます。シンボリックデバッグ情報はシンボルテーブル内に生成されます。統合デバッガはシンボリックデバッグ情報を利用して，プログラムのソースコードとコンパイラの生成する機械語コードを関連付けます。この関連付けによって，デバッガでプログラムを実行しながら同時にプログラムのソースコードを表示できるのです。

Delphi はデフォルトではシンボリックデバッグ情報を生成しますが，生成するかどうかを指定できます。

シンボリックデバッグ情報の生成を指定する方法は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選択します。

2.	［コンパイラ］ページタブをクリックしてデバッグオプションを表示します。

3.	［デバッグ情報(D)］と［ローカルシンボル(L)］にチェックマークを付けます。

生成したシンボリックデバッグ情報を統合デバッガで使用する場合は，コンパイラはシンボルテーブルをそれぞれに関連付けられた .DCU ファイルに格納します。

スタンドアロンデバッガの Turbo Debugger を使用する場合は，シンボリックデバッグ情報を最終的に EXE ファイルにも含めます (Delphi には Turbo Debugger は含まれません)。

プロジェクトのコンパイル済み .EXE ファイルにシンボリックデバッグ情報を含める方法は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選択します。

2.	［リンカ］ページタブをクリックしてリンカオプションを表示します。

3.	［TD32 デバッグ情報を含める(T)］にチェックマークを付けます。

メモ	実行形式ファイルにシンボリックデバッグ情報を含めると，.EXE ファイルのサイズはかなり大きくなります。したがって，デバッグ情報をファイルに含めるのはプロジェクトの開発段階だけにします。プログラムのデバッグを完了したら，デバッグ情報なしでプログラムをコンパイルし，.EXE ファイルのサイズを小さくします。

Before you begin1058008

統合デバッガのコマンドを実行する前に，統合デバッガが使用可能であることを確認します。

統合デバッガを使用可能にする方法は次のとおりです。

1.	［ツール(T)｜環境オプション(O)］を選択して［設定］ページタブをクリックします。

2.	必要に応じて［統合デバッガを使う(I)］にチェックマークを付けます。なお，このボックスにはデフォルトでチェックマークが付いています。

3.	プログラムを実行するときに Delphi 環境をアイコン化する場合は，［実行時アイコン化(M)］にチェックマークを付けます。


Running your program
Running your program1058009

Section topics	参照

プログラムをデバッグ情報とともにコンパイルしたら，Delphi からプログラムを起動してデバッグセッションを開始します。以後はデバッガの制御下でプログラムコードの実行，トレース，ステップ単位の実行を行います。

デバッガの下で実行したプログラムは，通常と同じように動作します。つまり，通常のとおりにウィンドウを作成し，ユーザー入力を受け付け，値を計算し，出力を表示します。プログラムが実行していない間はデバッガに制御が移るので，デバッガの機能を使用してプログラムの現在の状態を調べることができます。変数の値，呼び出しスタック上の関数リスト，プログラム出力を表示し，デバッグ対象のコードが設計のとおりに動作しているかどうか確認します。

デバッガをとおしてプログラムを実行すると，デバッガの作成するウィンドウでアプリケーションの動作を監視できます。デバッグセッションで最高の結果を得るには，デバッグ中にコードエディタとアプリケーションウィンドウの両方を表示できるように画面上の配置を工夫します。デバッグウィンドウとアプリケーションウィンドウを相互になめらかに切り替えるには，ウィンドウを重ねないで配置します。こうすればデバッグセッションでプログラムを速くスムーズに実行できます。

Specifying program arguments1058010

デバッグするプログラムでコマンドライン引数を使用する場合は，引数を Delphi の統合環境で指定できます。

プリケーションのコマンドライン引数を指定する方法は，次のとおりです。

1.	［実行(R)｜実行時引数(P)］を選択します。

2.	［実行時の引数(P)］編集ボックスで，統合デバッガを通して実行するプログラムに渡す引数を入力します。

3.	［OK］を選択します。

Debugging a DLL1058011

.EXE ファイルを指定すると，.DLL プロジェクトのデバッグを実行できます。

1.	［実行(R)｜実行時引数(P)］を選択します。

2.	［ホストアプリケーション(A)］編集ボックスで .EXE ファイルの名前を入力します。

3.	［OK］を選択します。


Controlling program execution
Controlling program execution1058012

Section topics	参照

デバッガの最も重要な機能は，プログラムの実行の制御です。プログラムを完全に制御して，行単位，関数単位，ブロック単位でコードを実行できます。したがって，プログラムを自由に実行または一時停止し，問題のセクションにすばやく到達できます。統合デバッガでプログラムの実行を制御するには，以下の方法があります。

カーソル位置までの実行

トレース実行とステップ実行

ブレークポイントまでの実行

プログラムの一時停止

デバッガをとおしたプログラムの実行は，ソースコードの行単位で行われます。つまり，統合デバッガは行単位の制御を行えます。デバッガでは単一のテキスト行にある複数のプログラム文も 1 行のコードとみなされます。つまり，単一のテキスト行にある複数の文は，個別にデバッグできません。逆に，複数のテキスト行に及ぶ 1 つの文は 1 行のコードとみなされます。


Running to the cursor location
Running to the cursor location1058013

Section topics	参照

デバッグセッションを開始したら，プログラムの問題のありそうな位置の直前まで，一気に実行したいことがあります。この位置で，すべてのデータ値に問題がないことを確かめます。問題がなければプログラムを別の位置まで実行し，再びデータ値に間違いがないことを確かめます。

プログラムを特定の場所まで実行する方法は，次のとおりです。

1.	コードエディタで，デバッグを開始 (または再開) するコード行にカーソルを配置します。

2.	以下のいずれかの方法でカーソル位置まで実行します。

コードエディタのスピードメニューで［カーソル位置まで実行(U)］を選択する

［実行(R)｜カーソル位置まで実行(C)］を選択する

〔F4〕を押す (デフォルト設定の場合)

カーソル位置までの実行では，コードエディタのテキストカーソルの示す位置まで，プログラムは一気に実行されます。カーソル位置のコードまで到達するとデバッガは制御を取り戻し，実行ポイントをこのコード行に置きます。

The execution point1058014

実行ポイントは，デバッガが次に実行するソースコード行を示します。カーソル位置までの実行やステップ実行などの後，デバッガ内でプログラムの実行が一時停止すると，デバッガは実行ポイントのコードを強調表示にして位置を示します。プログラムのトレース実行，ステップ実行，通常の実行のいずれを行う場合でも，必ずこの実行ポイントから開始されます。


Stepping through code
Stepping through code1058015

Section topics	参照

プログラムコード内を移動するには，トレース実行とステップ実行を使用するのが一番簡単です。この 2 つは似ていますが，コード内をステップする方法が異なります。これらの方法では，プログラムの文単位の実行を監視できます。1 ステップの実行後にプログラムは一時停止するので，デバッガでプログラムを各方面から調査できます。

Trace Into1058016

トレース実行では，プログラムを一度に 1 文ずつ実行します。デバッグ情報を持つ関数を呼び出す行に実行ポイントがあるときにトレース実行コマンドを選択すると，デバッガは関数内の最初の文に実行ポイントを配置して，関数内をステップ単位で実行し始めます。一方，デバッグ情報を持たない関数 (ライブラリ関数など) を呼び出す行に実行ポイントがあるときにトレース実行コマンドを選択すると，この関数を一気に実行して実行ポイントを関数呼び出しの次の文の上に配置します。

関数の最後の文に実行ポイントがあるときにトレース実行コマンドを選択すると，デバッガは関数から戻り，この関数の呼び出しの次のコード行に実行ポイントを配置します。

なお，トレース実行コマンドでプログラムコード内の文を連続的に実行することを，シングルステップといいます。

トレース実行は，以下のいずれかの方法で行います。

［実行(R)｜トレース実行(T)］を選択する

〔F7〕を押す (デフォルト設定の場合)

［トレース］スピードボタンをクリックする

Step Over1058017

ステップ実行もトレース実行と同じようにプログラムを一度に 1 文ずつ実行します。ただし，関数を呼び出す行に実行ポイントがあるときにステップ実行コマンドを発行すると，デバッガは関数をトレースせずに一気に実行し，関数呼び出しの次の文の上に実行ポイントを配置します。

ステップ実行は，以下のいずれかの方法で行います。

［実行(R)｜ステップ実行(S)］を選択する

〔F8〕を押す (デフォルト設定の場合)

［ステップ］スピードボタンをクリックする

関数によってトレース実行とステップ実行を使い分けることもできます。設計のとおりに動作することがわかっている関数への呼び出しは，ステップ実行で実行します。一方，動作に不安のある関数にはトレース実行を使用し，設計のとおりに動作するかどうかを調べます。

Debugging your application startup code1058018

トレース実行コマンドまたはステップ実行コマンドを選択してデバッグセッションを開始すると，実行ポイントはデフォルトでデバッグ情報を含む最初のコード行に配置されます。通常，デバッグ情報を含むコードは，ユーザーの記述したコードだけです。しかし，このデフォルトの設定をオーバーライドし，デバッグセッションを開始したときにプログラムの最初の実行文に実行ポイントを配置することもできます。この機能を利用すると，プロジェクトのスタートアップルーチンをデバッグできます。

プログラムの最初の実行文に移動する方法は，次のとおりです。

1.	［ツール(T)｜環境オプション(O)］を選択し，さらに［設定］ページタブをクリックします。

2.	［初期化部のデバッグ(T)］にチェックマークを付けます。

3.	トレース実行コマンドまたはステップ実行コマンドを選択してプログラムを実行します。


Running to a breakpoint
Running to a breakpoint1058019

Section topics	参照

プログラムを実行中に一時停止させるには，ソースコードの行にブレークポイントを設定します。ブレークポイントを設定すると，その場所までソースコードを一気に実行できます。この点では［カーソル位置まで実行］でカーソル位置まで実行するのと似ています。しかしそれとは異なり，ブレークポイントはコードの複数の場所に設定できます。しかも，各ブレークポイントをカスタマイズして，指定条件を満たした場合にのみプログラムの実行を一時停止させることもできます。ブレークポイントについての詳細は，「ブレークポイントの使い方」を参照してください。


Pausing the program
Pausing the program1058020

Section topics	参照

プログラムのステップ実行やトレース実行のほかに，実行中の一時停止も可能です。［実行(R)｜プログラムの停止(G)］を選択すると，次に実行ポイントがコード内に移動したときに，デバッガはプログラムを一時停止させます。停止した場所でプログラムの状態を調べ，その後通常のとおりにデバッグを続行できます。


Restarting the program
Restarting the program1058021

Section topics	参照

デバッグ中に，プログラムを最初から再実行したい場合もあります。たとえば，問題の場所を飛ばしてしまったり，変数やデータ構造を間違った値で壊してしまった場合などは，プログラムを再実行します。

現在のプログラムの実行を中止してプログラムをリセットするには，［実行(R)｜プログラムの終了(E)］を選択するか，〔Ctrl〕+〔F2〕(デフォルト設定の場合) を押します。

プログラムをリセットすると，すべての開いているプログラムファイルは閉じられます。また，VCL への呼び出しで割り当てたリソースは解放され，すべての変数もクリアされます。しかし，設定したブレークポイントや監視式は削除されないので，デバッグセッションを簡単に再開できます。


Using breakpoints
Using breakpoints1058022

Section topics	参照

ブレークポイントを設定すると，デバッグセッション中にソースコードの指定箇所でプログラムの実行を一時停止できます。ソースコードの問題の場所にブレークポイントを設定しておけば，プログラムを一気に実行して指定箇所で一時停止させることができます。プログラムの実行がブレークポイントに到達すると，プログラムは一時停止します。この場所で，ブレークポイントを含む行をコードエディタに表示し，プログラムの状態を調べることができます。


Setting breakpoints
Setting breakpoints1058023

Section topics	参照

ブレークポイントはプログラムの実行前でも統合デバッガの制御下でも随時設定できます。コード中の実行可能な行に設定したブレークポイントだけが有効です。コメント行，空白行，宣言などの実行可能でない行に設定したブレークポイントは無効で，プログラムを実行しても機能しません。

ブレークポイントを設定するには，ブレークポイントを設定するコード行をコードエディタで選択し，以下のいずれかを行います。

コードエディタで，ブレークポイントを設定する行の左余白をクリックする

〔F5〕を押す (デフォルト設定の場合)

コードエディタのスピードメニューで［ブレークポイントの設定(K)］を選択する

［実行(R)｜ブレークポイントの追加(B)］を選択し，次に［ブレークポイントの設定］ダイアログボックスで［新規作成(N)］を選択して新しいブレークポイントを設定する

ブレークポイント一覧ウィンドウのスピードメニューで［ブレークポイントの追加(A)］を選択する

また，コードの行番号を指定してブレークポイントを設定したい場合は［実行(R)｜ブレークポイントの追加(B)］を選択し，［行番号(L)］ボックスに行番号を入力します。［ブレークポイントの設定］ダイアログボックスの設定に間違いがなければ，［新規作成(N)］を選択してブレークポイントの入力を完了します。

ブレークポイントを設定すると，ブレークポイントを設定した行が強調表示になり，ブレークポイント行の左余白には停止記号のマークが表示されます。

Invalid breakpoints1058024

実行可能なコード行に設定されていないブレークポイントは不正とみなされます。たとえば，コメント，空白行，宣言に設定されたブレークポイントは不正です。不正なブレークポイントを設定すると，プログラムを実行したときにデバッガは警告ボックスを表示します。この状態を修正するには，警告ボックスを閉じてブレークポイント一覧ウィンドウで不正なブレークポイントを削除し，正しい場所にブレークポイントを設定し直します。なお，不正なブレークポイントに対する警告を無視することもできます。この場合，プログラムを実行すると Delphi はすべての不正なブレークポイントを無効にします。

メモ	コンパイルのリンク段階で，リンカはプログラムでまったく呼び出されないコード行をデッドコードとしてマークします。統合デバッガはデッドコードに設定されたブレークポイントを無効なものとしてマークします。

Setting breakpoints after starting a program1058025

プログラムの実行中でも，コードエディタにアクセスしてデバッガに切り替え，ブレークポイントを設定できます。アプリケーションに戻ると新しいブレークポイントは有効になり，ブレークポイントに到達するとアプリケーションは一時停止します。


Working with breakpoints
Working with breakpoints1058026

Section topics	参照

ブレークポイント一覧ウィンドウには，すべてのブレークポイントがファイル名と行番号とともに一覧表示されます。また，それぞれのブレークポイントについて，関連付けられた条件と通過回数も表示されます。無効または不正なブレークポイントは，ブレークポイント一覧で淡色表示になります。

ブレークポイント一覧ウィンドウを開くには次のようにします。

［表示(V)｜ブレークポイント(B)］を選択する

ブレークポイント一覧を使用すると，すべてのブレークポイントを表示して管理できるので，設定したブレークポイントを探すためにソースファイルを検索する必要はありません。また，一覧の各ブレークポイントを右クリックして現れるスピードメニューのコマンドで，ブレークポイント位置のコードの表示や編集もできます。

Viewing and editing code at a breakpoint1058027

コードエディタウィンドウに表示されていないブレークポイントでも，ソースコード内の位置をブレークポイント一覧ウィンドウから簡単に探せます。

ブレークポイント一覧ウィンドウからコードエディタ内のブレークポイントを探す方法は次のとおりです。

1.	ブレークポイント一覧ウィンドウで探したいブレークポイントを選択します。

2.	スピードメニューで［ソースの表示(V)］または［ソースの編集(S)］を選択します。

コードエディタが更新されてブレークポイントの位置を示します。［ソースの表示(V)］を選択するとブレークポイント一覧ウィンドウはアクティブなままになるので，そこでブレークポイントを変更したり別のブレークポイントを表示することができます。［ソースの編集(S)］を選択すると，コードエディタはブレークポイントを含む行にフォーカスを移動するので，その位置のソースコードを変更できます。

Disabling and enabling breakpoints1058028

無効 (使用不可) にしたブレークポイントは，「隠された」状態になります。つまり，無効にしたブレークポイントの設定は残りますが，ブレークポイントとして機能しなくなるので，プログラムはそこでは停止しません。設定した条件ブレークポイントを後で使用する場合などは，ブレークポイントを無効にしておくと便利です。

現在有効なブレークポイントを無効にする方法は次のとおりです。

1.	ブレークポイント一覧ウィンドウを開いて，無効にするブレークポイントを選択します。

2.	ブレークポイント一覧スピードメニューで［有効(E)］を選択します。
［有効(E)］のチェックマークが消えます。このメニューコマンドは，ブレークポイントの有効と無効を切り替えます。

また，ブレークポイントを選択していない状態で，ブレークポイント一覧スピードメニューの［すべて無効化(I)］を選択して，現在のすべてのブレークポイントを無効にすることもできます。

ブレークポイントを再び使用可能にする方法は，次のとおりです。

1.	ブレークポイント一覧ウィンドウでブレークポイントを選択します。

2.	スピードメニューから［有効(E)］を選択します。

ブレークポイントを選択していない状態で，ブレークポイント一覧スピードメニューの［すべて有効化(E)］を選択してすべてのブレークポイントを有効にすることもできます。

Deleting breakpoints1058029

ブレークポイント位置のコードを調べ終えたら，デバッグセッションからブレークポイントを削除できます。ブレークポイントを削除するには，コードエディタまたはブレークポイント一覧ウィンドウを使用します。

ブレークポイントを削除するには，以下の方法があります。

コードエディタで，ブレークポイントを含む行にテキストカーソルを移動して〔F5〕を押すか，スピードメニューの［ブレークポイントの設定(K)］を選択する

コードエディタウィンドウの停止記号マークをクリックして，関連付けられたブレークポイントを削除する

ブレークポイント一覧で削除するブレークポイントを強調表示し，スピードメニューの［削除(D)］を選択する

現在設定されているすべてのブレークポイントを削除するには，ブレークポイント一覧ウィンドウのスピードメニューで［すべて削除(D)］を選択する

注意	削除したブレークポイントは，元に戻せません。


Modifying breakpoint properties
Modifying breakpoint properties1058030

Section topics	参照

ブレークポイントのプロパティを表示して変更するには，ブレークポイント一覧でブレークポイントを選択して，スピードメニューの［プロパティ(R)］を選択します。［ブレークポイントの設定］ダイアログボックスが表示されます。

［ブレークポイントの設定］ダイアログボックスでは，ブレークポイントのプロパティを調べるだけでなく，ブレークポイントの位置の変更，条件ブレークポイントの設定，ブレークポイントのパスカウントの設定を行えます。

Creating conditional breakpoints1058031

デフォルトでは，プログラムの実行はブレークポイントに到達するたびに必ず停止します。しかし，［ブレークポイントの設定］ダイアログボックスでブレークポイントをカスタマイズし，指定した条件を満たす場合にのみアクティブにすることもできます。

統合デバッガでは以下の 2 種類の条件をブレークポイントに追加できます。

Boolean expressions

Pass counts

Setting Boolean conditions1058032

［ブレークポイントの設定］ダイアログボックスの［ブレーク条件(C)］編集ボックスには，プログラムの実行中にブレークポイントに到達したときに評価する式を指定できます。式の評価が真 (0 以外) の場合，ブレークポイントはプログラムの実行を一時停止します。式の評価が偽 (0) の場合，プログラムは停止しません。

条件ブレークポイントは，変数が特定範囲にあるときのプログラムの動作や，特定のフラグを設定したときの影響を確認するような場合に便利です。

たとえば，変数 mediumCount が 10 を超えたときにのみブレークポイントでプログラムを一時停止させることを考えます。この条件ブレークポイントを設定する方法は次のとおりです。

1.	コードエディタで，ブレークポイントを設定するコード行にカーソルを移動して〔F5〕を押します。

2.	［表示(V)｜ブレークポイント(B)］を選択してブレークポイント一覧を開きます。

3.	設定したブレークポイントを右クリックし，スピードメニューで［プロパティ(R)］を選択します。［ブレークポイントの設定］ダイアログボックスが開きます。

4.	［ブレーク条件(C)］編集ボックスに次の式を入力します。

  mediumCount > 10

5.	［変更(M)］を選択して設定を確認します。

メモ	［ブレーク条件(C)］編集ボックスには，どのような言語式 (Object Pascal 言語の式) でも入力できます。ただし，式で使用するすべてのシンボルはブレークポイントの位置からアクセスできなければなりません。また，関数呼び出しは使用できません。

また，Assert 手続きを使って，デバッグ中に論理値の状態をテストすることもできます。詳細はオンラインヘルプを参照してください。

Using pass counts1058033

［パスカウント(P)］編集ボックスでは，ブレークポイントをアクティブにするためにブレークポイントを通過しなければならない回数を指定できます。プログラムの実行が一時停止するのは，ブレークポイントに到達した回数が，パスカウントとして指定した回数になったときです。なお，パスカウントのデフォルトの設定は 0 ですが，1 と同等に扱われます。

パスカウントの値は，プログラムの実行がブレークポイントの行に到達するごとにデクリメント (1 ずつ減算) されます。パスカウントが 1 になったときブレークポイントはアクティブになり，プログラムの実行はその行で一時停止します。

n 回目の繰り返しでループが失敗すると思われる場合などは，パスカウントを指定すると便利です。また，何回目の繰り返しでループが失敗するのかわからない場合は，パスカウントに最大のループ回数を設定してプログラムを実行します。ループが失敗したら，［パスカウント(C)］ボックスに残っている数値を調べてプログラムがループを通過した回数を計算します。

ブレークポイントでパスカウントを論理条件と組み合わせて使用すると，条件が n 回目に真となったときにプログラムの実行を一時停止させることができます。このとき，パスカウントは条件が真のときにのみデクリメントされます。


Customizing the breakpoint and execution point colors
Customizing the breakpoint and execution point colors1058034

Section topics	参照

実行ポイント行，有効なブレークポイント行，無効なブレークポイント行，不正なブレークポイント行のそれぞれについて，表示色をカスタマイズできます。

実行ポイント行の色とブレークポイント行の色を設定する方法は，次のとおりです。

1.	［ツール(T)｜環境オプション(O)］を選択します。

2.	［色］ページタブを選択します。

3.	［文法要素(E)］リストで［実行中の行］，［有効なブレークポイント］，［無効なブレークポイント］，［不正なブレークポイント］のいずれかを選択し，希望する前景色と背景色を設定します。


Examining program data values
Examining program data values1058035

Section topics	参照

プログラムの実行やステップ単位の実行をとおしてプログラムを多方面からテストできるわけですが，通常は，バグを発見するのにプログラムの変数の値も調べます。たとえば，for ループをステップ単位で実行するときのインデックス変数の値や，関数呼び出しに渡すパラメータの値がわかると便利です。

統合デバッガでは，以下のツールでプログラムのデータ値を調べることができます。

監視式一覧ウィンドウ

［評価/変更］ダイアログボックス

自動支援機能の式評価

呼び出し履歴ウィンドウ

データの評価には式を使用します。式を構成するのは，定数，変数，構造化されたデータの値，言語演算子です。なお，関数呼び出しを除いて，代入演算子の右側に使用できる式はデバッグ式としても使用できます。


Watching expressions
Watching expressions1058036

Section topics	参照

監視式を使うと，プログラムの実行中に変化する変数や式の値を監視できます。監視式を入力した監視式一覧ウィンドウには式の現在値が表示されます。実行中のプログラムで監視式内の変数の値が更新されると，それに合わせて監視式の値も更新されます。

実行ポイントが移動して監視式内の変数が未定義の位置になると，その監視式全体が未定義になります。監視式を評価できる位置に実行ポイントが戻ると，監視式一覧は再び監視式の現在値を表示します。

監視式一覧ウィンドウを開くには次のようにします。

［表示(V)｜監視式(W)］を選択する

監視式はコードエディタで設定するのが最も簡単です。設定方法は次のとおりです。

1.	監視する式を選択します。

2.	コードエディタのスピードメニューで［この単語を監視式に追加(A)］を選択し，監視式一覧に式を追加します。

監視式を作成するには次の方法もあります。

1.	以下のいずれかの方法で［監視式のプロパティ］ダイアログボックスを開きます。

メインメニューで［実行(R)｜監視式の追加(W)］を選択する

コードエディタのスピードメニューで［この単語を監視式に追加(A)］を選択する

〔Ctrl〕+〔F5〕を押す (デフォルト設定の場合)

監視式一覧で監視式をダブルクリックする

監視式一覧で監視式を選択し，スピードメニューの［監視式の編集(E)］を選択する

2.	［評価する式(E)］編集ボックスに監視する式を入力します。または，ドロップダウンリストで以前に入力した式を選択します。

Formatting watch expressions1058037

［監視式のプロパティ］ダイアログボックスでは，監視式の表示形式を指定できます。デフォルトでは，デバッガは整数値を 10 進数で表示します。しかし，［監視式のプロパティ］ダイアログボックスの［16 進整数(X)］ボタンを選択すると，整数の監視式を 16 進数で表示できます。

配列などのデータ構造の要素に監視式を設定すると，連続したデータ要素の値を表示できます。たとえば，xarray という 5 つの整数の配列があるとします。配列の 5 つの値をすべて表示するには［監視式のプロパティ］ダイアログボックスの［繰り返し回数(U)］編集ボックスに 5 を入力します。ただし［繰り返し回数(U)］編集ボックスを使用する場合，監視式は 1 つのデータ要素を表していなければなりません。

浮動小数点式の表示形式を指定するには，監視式一覧に表示する有効桁数を［桁数(G)］編集ボックスに指定します。

Disabling a watch1058038

監視式一覧内の式を削除しないで一時的に使用不可にしておきたい場合は，この監視式を無効にします。監視式を無効にするとデバッガの処理が高速化します。デバッガはプログラムの実行やステップ実行で式を監視せずに済むようになるからです。

［監視式のプロパティ］ダイアログボックスでは，各監視式の左横に［有効(N)］チェックボックスが付いています。監視式を設定すると，デバッガはこのチェックボックスにチェックマークを付けて監視式を使用可能にします。

監視式を無効にするには，以下のどちらかを行います。

監視式一覧ウィンドウで監視式をダブルクリックし，［監視式のプロパティ］ダイアログボックスを開いて［有効(N)］のチェックマークをはずす

監視式一覧で監視式を選択し，スピードメニューの［監視式の無効化(I)］を選択する

なお，スピードメニューの［すべての監視式の無効化(B)］を選択すれば，現在のすべての監視式を無効にできます。監視式を再び使用可能にするには，［監視式のプロパティ］ダイアログボックスで［有効(N)］にチェックマークを付けます。または監視式一覧ウィンドウで監視式を指定してスピードメニューの［監視式の有効化(N)］を選択するか，［すべての監視式の有効化(L)］を選択します。

Deleting a watch1058039

監視式を削除する方法は，次のとおりです。

1.	監視式一覧ウィンドウで式を選択します。

2.	スピードメニューの［監視式の削除(D)］を選択します。

スピードメニューの［すべての監視式の削除(T)］を選択してすべての監視式を削除することもできます。

注意	削除した監視式は，元に戻せません。


Evaluating and modifying expressions
Evaluating and modifying expressions1058040

Section topics	参照

［評価/変更］ダイアログボックスを使うと，式の評価やデータ項目の値の変更ができます。このダイアログボックスでは，デバッグセッション中に変数の値やデータ構造の項目の値を変更できるという点で，監視式よりも便利です。たとえば，変数の値を変更することでバグを修正できるかもしれないと考えたとします。このとき，デバッガを終了し，ソースコードを変更し，プログラムを再コンパイルする前に，このバグの修正を試してみることができます。

Evaluating expressions1058041

［実行(R)｜評価/変更(V)］を選択して［評価/変更］ダイアログボックスを開きます。

デフォルトとして，現在のコードエディタのカーソル位置にある単語が［評価する式(E)］編集ボックスに入ります。このデフォルト式を受け入れるか，別の式を入力するか，前に評価した式をヒストリリストから選択します。

式を評価するには次のようにします。

［評価/変更］ダイアログボックスの下部にある［評価(V)］ボタンをクリックする

このダイアログボックスでは，どのような言語式でも評価できます。ただし，以下を除きます。

現在の実行ポイントからアクセスできないローカル変数や静的変数

関数および手続きの呼び出し

メモ	［評価/変更］ダイアログボックスでは，プログラムの実行中にオブジェクトプロパティの値を表示して変更できます。プロパティを表示するにはプロパティ名を明示的に指定します。たとえば，Button1 の Caption プロパティを評価するには次の式を入力します。

Button1.Caption

式を評価すると，このダイアログボックスの［結果(R)］フィールドに式の現在値が表示されます。必要であれば，［評価する式(E)］編集ボックスに入力された式の最後にカンマ (,) と形式指定子を追加して値の表示形式を変更できます。表 14.1 に有効な形式指定子をまとめます。

文字	対象の型	機能
H または  X	整数	16 進数の表示。整数値を 16 進数で表し，先頭に $ を付ける。データ構造内の整数値にも適用可能
C	Char 型， 文字列	文字の表示。表示できない ASCII 文字は #nn の形式で表示する
D	整数	10 進数の表示。整数値を 10 進数で表示する。データ構造内の整数値にも適用可能
Fn	浮動小数点	浮動小数点の表示。n には有効桁数を指定する (範囲 2～8。デフォルトは 7)
nM	すべて	メモリダンプの表示。指定の式をアドレスとして，それ以降の n バイトを表示する。n を指定しないと，デフォルトで変数の型のバイトサイズを表示する デフォルトでは，各バイトを 2 桁の 16 進数で表示する。C，D，H，S，X の各指定子と M を組み合わせてバイトの表示形式を変更できる
P	ポインタ	ポインタの表示。ポインタを 8 桁のアドレスとして表示する
R	レコード， クラス， オブジェクト	レコード，クラス，オブジェクトの表示。フィールド名と値の両方を (X: 1; Y: 10; Z: 5) の形式で表示する。(1, 10, 5) のようには表示しない
S	Char 型， 文字列	文字列の表示。表示できない ASCII 文字は #nn の形式で表示する。ここで nn は ASCII の文字コードを示す。メモリダンプでのみ有効 (nM を参照)
たとえば，結果を 16 進数で表示するには，式の後に続けて，H を入力します。浮動小数点数を小数点以下 3 桁まで表示するには，式に続けて，F3 と入力します。

Modifying the values of variables1058042

評価した変数やデータ構造の項目の値は変更できます。デバッグセッション中にデータ項目の値を変更すると，バグの修正後や異なる状況でのコードの動作を確認できます。

データ項目の値を変更する方法は，次のとおりです。

1.	［評価/変更］ダイアログボックスを開き，変更する変数またはデータ項目の名前を［評価する式(E)］編集ボックスに入力します。

2.	［評価(V)］をクリックしてデータ項目を評価します。

3.	［新しい値(N)］編集ボックスに値を入力するか，ドロップダウンリストで値を指定し，さらに［変更(M)］をクリックしてデータ項目を更新します。

メモ	デバッガによるデータ項目の値の変更は，その回のプログラム実行にのみ有効です。つまり，［評価/変更］ダイアログボックスによる変更は，プログラムのソースコードやコンパイル済みのプログラムには影響しません。変更を固定するにはコードエディタでプログラムのソースコードを変更し，プログラムを再コンパイルします。

プログラムのデータ値を変更する場合は，以下の点に注意してください。

配列やデータ構造の個別の変数や要素は変更できますが，配列全体やデータ構造全体の内容は変更できません。

［新しい値(N)］ボックスの式を評価した結果は，代入先の変数と代入互換性がなければなりません。もともと，代入するとコンパイル時エラーや実行時エラーを起こすような変更値は有効ではありません。

関数に渡した型なしパラメータは直接変更できませんが，型キャストすれば新しい値を代入できます。

注意	値 (特にポインタ値と配列インデックス) を変更すると，ほかの変数やデータ構造を上書きする恐れがあります。デバッガでプログラムの値を変更する場合は十分に注意してください。

Tool Tip Expression Evaluation1058043

式評価は，デバッグ中にプログラムが停止したときに式の値を手早くチェックできる方法です。コードエディタで変数を指すと，ポップアップウィンドウにその変数の値が表示されます。式評価についての詳細は，「コード記述に必要なヘルプ」を参照してください。


Viewing function calls
Viewing function calls1058044

Section topics	参照

デバッグでは，現在のプログラム位置までの関数呼び出しの経過がわかると便利です。呼び出し履歴ウィンドウでは，現在までの関数呼び出しの経過を表示できます。このウィンドウには，各関数の呼び出しに使用したパラメータのリストも表示されます。

呼び出し履歴ウィンドウを表示するには次のようにします。

［表示(V)｜呼び出し履歴(C)］を選択する

呼び出し履歴ウィンドウの一番上には，プログラムで最後に呼び出した関数が表示されます。1 つ前に呼び出した関数がその下に続きます。以下，同じように続いてリストの最後にはプログラムで最初に呼び出した関数が表示されます。このウィンドウには現在読み込まれているシンボルテーブルの関数だけが表示されます。

呼び出し履歴ウィンドウは，コードをステップ実行するかわりに誤ってトレースしてしまった場合には特に便利です。呼び出し履歴ウィンドウを使用すると，現在の関数を呼び出した場所に戻ってデバッグを再開できます。

呼び出し履歴ウィンドウの使い方は，次のとおりです。

1.	呼び出し履歴ウィンドウで，誤ってトレースした関数を呼び出した関数をダブルクリックします。つまり，呼び出し履歴ウィンドウで 2 番目に表示されている関数をダブルクリックします。関数呼び出しの次の位置がコードエディタ上で強調表示されます。

2.	コードエディタをアクティブにして，強調表示されている関数呼び出しの次の位置にカーソルを移動します。

3.	コードエディタのスピードメニューで［カーソル位置まで実行(R)］を選択するか，〔F4〕キーを押します。


Navigating to function calls
Navigating to function calls1058045

Section topics	参照

呼び出し履歴ウィンドウを使用すると，特定の関数呼び出しの位置でソースコードを表示，編集できます。

関数呼び出しのソースコードを表示または編集するには次のようにします。

呼び出し履歴ウィンドウのスピードメニューからそれぞれ［ソースの表示(V)］または［ソースの編集(S)］を選択する

［ソースの編集(S)］の場合は，コードエディタがフォーカスを得るので関数位置のソースコードを変更できます。一方，［ソースの表示(V)］の場合は，呼び出し履歴ウィンドウにフォーカスが残ります。

呼び出し履歴ウィンドウの一番上の関数を選択していると，［ソースの表示(V)］や［ソースの編集(S)］は，現在の関数の実行ポイントのある場所をコードエディタに表示します。ほかの関数呼び出しを選択していると，デバッガはその関数呼び出しをコードエディタに表示します。


Handling hardware and language exceptions
Handling hardware and language exceptions1058046

Section topics	参照

Delphi はデバッグ中に例外処理を制御する機構を提供しています。さらに，Delphi はほとんどのハードウェア例外を Object Pascal 言語例外として扱うことで，デバッグセッションを簡単にしています。つまり，Delphi は Delphi アプリケーションで生成されたハードウェア例外をトラップするので，プログラムの実行によってシステムクラッシュが起きる前に，エラーを回復できます。

デバッグセッション中にハードウェア例外や言語例外が発生した場合，VCL は例外を示すダイアログボックスを表示します。なお，このダイアログボックスはプログラムのデバッグ中であるかどうかに関係なく表示されます。［OK］を選択してダイアログボックスを閉じると，プログラムの実行は続行し，アプリケーションのデバッグも継続できます。

例外の発生時にプログラムの実行を一時停止させる方法は，次のとおりです。

1.	［ツール(T)｜環境オプション(O)］を選択し，［設定］タブをクリックします。

2.	［例外でデバッガに戻る(B)］にチェックマークを付けます。なお，このチェックボックスにはデフォルトでチェックマークが付きます。

3.	デバッグセッションを開始します。

［例外でデバッガを開く(B)］にチェックマークを付けると，Delphi は例外の発生時にエラーダイアログボックスを表示します。［OK］を選択してダイアログボックスを閉じるとコードエディタが開きます。実行ポイントは例外を発生させたコード行にあります。ここでプログラムコードを調べ，例外の発生した理由を判断することができます。この場所からプログラムの実行を継続すると，VCL は例外ダイアログボックスを表示します。

メモ	発生したハードウェア例外によっては，システムが不安定な状態になります。したがって，通常は例外が発生したらプログラムを終了するのが一番です。プログラムエラーを解決したらデバッグセッションを再開します。


See also1058047

開発環境の有効利用


Handling exceptions
Handling exceptions1062001

Section topics	参照

Delphi は堅固なアプリケーションを構築する機構を提供しています。堅固なアプリケーションとは，エラーから回復できる場合は回復し，やむを得ない場合はデータやリソースを失わずにシャットダウンするという一貫したエラー処理方法を持つアプリケーションを意味します。

Delphi では，エラーは例外という形式で示されます。例外は発生したエラーの種類と場所を示すオブジェクトです。Delphi のランタイムライブラリとすべての標準コンポーネントは例外を生成し，また，例外に応答します。

例外を使用して強固なアプリケーションを作成するためには，以下の基本事項について理解する必要があります。

コードのブロックの保護

リソース割り当ての保護

RTL 例外の処理

コンポーネント例外の処理

サイレント例外

独自の例外の定義


Protecting blocks of code
Protecting blocks of code1062002

Section topics	参照

堅固なアプリケーションの条件は，例外の発生を認識して対処できることです。例外に対処する応答を指定しなくても，アプリケーションはエラーを示すメッセージボックスを表示します。したがって，残る仕事はエラーの発生しやすい場所を特定して応答を定義することです。特にデータやシステムリソースを破壊する恐れのあるエラーに注意します。

例外への応答を作成するときは，そのコードブロックを作成します。エラーに対して同じ種類の応答をする一連のコードがある場合，それらを 1 つのブロックにまとめてそのブロック全体に適用するエラー応答を定義できます。

例外への応答を定義したブロックは，プロテクトブロックと呼びます。プロテクトブロックは，アプリケーションの中止やデータの損傷を起こすエラーから保護されているブロックです。

コードのブロックを保護するには，以下について理解する必要があります。

例外への応答

例外と実行経路

例外応答のネスト


Responding to exceptions
Responding to exceptions1062003

Section topics	参照

エラー条件が成立すると，アプリケーションは例外を生成します。つまり，例外オブジェクトを作成します。例外を生成した後のアプリケーションは，クリーンアップコードを実行するか，例外を処理するか，または，クリーンアップコードの実行と例外処理の両方を行います。

Executing cleanup code1062004

例外に応答する最も簡単な方法は，クリーンアップコードを実行することです。この対処ではエラーの原因となった状態を修正しませんが，アプリケーションが不安定な状態になることを防止できます。

エラーの有無に関係なく，アプリケーションに割り当てられたリソースを解放するには，通常この方法を使用します。詳細は 15-4 ページの「リソース割り当ての保護」を参照してください。

Handling the exception1062005

例外処理とは，特定の例外に専用の応答を作成することです。例外処理ではエラーの原因を解消し，例外オブジェクトを廃棄し，アプリケーションの実行を継続します。

アプリケーションをエラーから回復して実行を継続するには，通常，例外ハンドラを定義します。対象となる例外は，存在しないファイルのオープン，満杯のディスクに対する書き込み，有効な範囲を超えた計算などです。ファイルが見つからないというような，簡単に修正して再試行できる例外もありますが，メモリ不足のようにアプリケーションやユーザーでは対処しにくい例外もあります。詳細はこの章の「RTL 例外の処理」，「コンポーネント例外の処理」，「独自の例外の定義」を参照してください。


Exceptions and the flow of execution
Exceptions and the flow of execution1062006

Section topics	参照

Object Pascal ではエラー処理を簡単にアプリケーションに組み込めます。なぜなら，例外はコードの通常の実行経路とは別の場所に記述するからです。アルゴリズムの本流からエラーチェックとエラー処理をはずすことで，コードの記述を簡略化できます。

プロテクトブロックを宣言することは，ブロック内で発生する例外に専用の応答を定義することです。ブロックで例外が発生すると，ブロックを抜ける前にただちに定義した応答が実行されます。

Example1062007

プロテクトブロックを含むコードの例を次に示します。プロテクトブロックで例外が発生すると，例外処理部に実行が移り，例外処理部は警告音を鳴らします。実行はブロック外で再開します。

...

try	{ プロテクトブロックを開始 }

  Font.Name := 'Courier';	{ 例外の発生場所が ... }

  Font.Size := 24;	{ ...ブロック内の場合 ... }

  Color := clBlue;

except	{ ...ここにジャンプする }

  on Exception do MessageBeep(0);	{ 例外処理として警告音を鳴らす }

end;

...	{ このプロテクトブロックの外から実行が再開される }


Nesting exception responses
Nesting exception responses1062008

Section topics	参照

ブロック内で起こる例外への応答はコードで定義します。Pascal ではブロックを別のブロック内にネストできます。したがって，すでに専用の応答を定義されたブロック内でも，別のブロックをネストしてさらに専用の応答を定義できます。

最も簡単な例では，リソース割り当てを保護するプロテクトブロックを作成し，この中に別のブロックを定義して，ほかのリソースを割り当てて保護する場合があります。わかりやすく示すと次のようになります。

ネストしたブロックを使用すれば，特定の例外に対して，内側のブロックにローカルな処理を定義し，外側のブロック (封入ブロック) の処理をオーバーライドすることもできます。わかりやすく示すと次のようになります。

ネストされたブロックで，応答する例外の種類が異なっていてもかまいません。リソース保護をほかの例外処理ブロック内にネストするようなことも可能です。


Protecting resource allocations (try..finally block)
Protecting resource allocations1062009

Section topics	参照

堅固なアプリケーションで重要なのは，例外が発生してもアプリケーションで割り当てたリソースを必ず解放することです。たとえば，アプリケーションでメモリを割り当てた場合は，このメモリを最終的に必ず解放します。ファイルを開いた場合は，後で必ず閉じます。

記述したコードだけが例外を生成するとは限りません。たとえば，RTL ルーチンやアプリケーションの別のコンポーネントの呼び出しが例外を生成する場合もあります。このようなエラーが発生した場合でも，割り当てたリソースを必ず解放するようにコードを記述する必要があります。

リソースを効果的に保護するためには，以下の点を理解している必要があります。

保護を必要とするリソースの種類

リソース保護ブロックの作成


What kind of resources need protection?
What kind of resources need protection?1062010

Section topics	参照

通常，割り当てと解放の両方のコードをアプリケーションに含めることで，アプリケーションで割り当てたリソースを解放できます。しかし，例外が発生したときにも，アプリケーションがリソースを解放するコードを実行できるように保証しなければなりません。

一般的に，必ず解放しなければならないリソースは以下のとおりです。

ファイル

メモリ

Windows リソース

オブジェクト

Example1062011

たとえば，次のイベントハンドラではメモリを割り当てた後でエラーが発生しますが，メモリを解放するコードは実行されません。

procedure TForm1.Button1Click(Sender: TComponent);

var

  APointer: Pointer;

  AnInteger, ADividend: Integer;

begin

  ADividend := 0;

  GetMem(APointer, 1024);	{ 1KB のメモリを割り当てる }

  AnInteger := 10 div ADividend;	{ この文はエラーになる }

  FreeMem(APointer, 1024);	{ ここまで到達しない }

end;

これほど明白なエラーはあまりないと思いますが，この例は重要な点を示しています。つまり，0 による除算エラーが発生した場合，実行はブロック外に移行するので FreeMem 文でメモリを解放するところまで到達しないということです。

GetMem で割り当てたメモリを必ず FreeMem で解放させるには，コードをリソース保護ブロックに入れます。


Creating a resource-protection block
Creating a resource-protection block1062012

Section topics	参照

例外が発生した場合も割り当てたリソースを解放するには，リソースを使用するコードをプロテクトブロック内に埋め込み，このブロックの特定箇所にリソースを解放するコードを入れることです。保護されたリソース割り当ての例を次に示します。

{ リソースを割り当てる }

try

  { リソースを使用する文 }

finally

  { リソースを解放する }

end;

try..finally ブロックの重要な点は，プロテクトブロックで例外が発生しても，プロテクトブロックの finally 部にあるすべての文は必ず実行されるという点です。ブロックの try 部のコードか，または try 部のコードから呼び出されるルーチンが例外を生成すると，ただちに実行は finally 部に移ります。finally 部はクリーンアップコードと呼ばれます。例外が発生しない場合，クリーンアップコードは通常の順序で実行されます。つまり，try 部のすべての文の後に実行されます。

Example1062013

メモリを割り当てた後でエラーが発生した場合も，割り当てたメモリを解放するイベントハンドラを次に示します。

procedure TForm1.Button1Click(Sender: TComponent);

var

  APointer: Pointer;

  AnInteger, ADividend: Integer;

begin

  ADividend := 0;

  GetMem(APointer, 1024);	{ 1KB のメモリを割り当てる }

  try

    AnInteger := 10 div ADividend;	{ この文はエラーになる }

  finally

    FreeMem(APointer, 1024);	{ エラーが発生しても実行はここから再開する }

  end;

end;

終了コードは例外の発生に関係なく実行されます。try 部の文が例外を生成しない場合も終了コードは実行されます。

メモ	finally 部は例外を処理しません。実際，終了コードは例外が発生したかどうかの情報を持っていないので，例外を処理するかどうかを決められません。finally 部で例外が発生すると，アプリケーションはまず終了コードを実行し，次に例外を処理しないままブロックを抜けます。例外の処理は，そのリソース保護ブロックの外側のブロックで行われます。


Handling RTL exceptions
Handling RTL exceptions1062014

Section topics	参照

ランタイムライブラリ (RTL) のルーチンである算術関数やファイル処理手続きなどを呼び出すコードを記述している場合，RTL はエラーを例外としてアプリケーションに報告します。デフォルトでは，RTL 例外が生成したメッセージがアプリケーションをとおしてユーザーに通知されます。しかし，独自の例外ハンドラを定義して，このデフォルトとは異なる方法で RTL 例外を処理することもできます。

また，デフォルトではメッセージを表示しないサイレント例外もあります。

RTL 例外を効果的に処理するためには，以下について理解している必要があります。

RTL 例外とは何か

例外ハンドラの作成

デフォルト例外ハンドラの提供

例外クラスの処理

例外の再生成


What are the RTL exceptions?
What are the RTL exceptions?1062015

Section topics	参照

ランタイムライブラリの例外は SysUtils ユニットに定義されています。ランタイムライブラリのすべての例外は，Exception という汎用の例外オブジェクト型から派生しています。Exception は，RTL 例外がデフォルトで表示するメッセージの文字列を提供します。

RTL が生成する例外には，8 種類あります。次の表で説明します。

エラーの種類	原因	説明
入出力	ファイルや I/O デバイスへのアクセスエラー	ほとんどの I/O 例外はファイルにアクセスするときに Windows から返されるエラーコードに関連する
ヒープ	メモリの動的使用でのエラー	ヒープエラーは使用可能なメモリが足りなくなったとき，またはアプリケーションがヒープを指していないポインタを破棄するときに発生する
整数演算	整数型の式の不正な演算	0 による除算，範囲外の数値または式，オーバーフローを含むエラー
浮動小数点演算	実数型の式の不正な演算	浮動小数点エラーは，ハードウェアコプロセッサまたはソフトウェアエミュレータにより発生する。未定義の命令，0 による除算，オーバーフロー，アンダーフローを含む
型キャスト	as 演算子を使う不正な型キャスト	オブジェクトの互換性のない型へのキャスト
変換	不正な型変換	IntToStr，StrToInt，StrToFloat のような型変換関数が，パラメータを指定された型に変換できないときに変換例外を引き起こす
ハードウェア	システムの条件	ハードウェア例外は，プロセッサまたはユーザーがなんらかの種類のエラー条件を生成したことを示す。アクセス違反，スタックオーバーフロー，キーボード割り込みなど
変数	不正な型強制	互換性のある型に強制できない変数を参照しているときに発生するエラー
RTL 例外の種類については，オンラインヘルプで SysUnits を参照してください。


Creating an exception handler (try..except block)
Creating an exception handler1062016

Section topics	参照

例外ハンドラとは，コードのプロテクトブロック内で発生する特定の例外を処理するコードです。

例外ハンドラを定義するには次のようにします。

保護したいコードを例外処理ブロックに記述し，例外処理文をブロックの except 部に指定する

一般的な例外処理ブロックを次に示します。

try

  { 保護したい文 }

except

  { 例外処理文 }

end;

アプリケーションでは，try 部の文の実行中に例外が発生した場合だけ，except 部の文を実行します。try 部の文には，try 部のコードで呼び出したルーチンも含みます。つまり，try 部のコードで呼び出したルーチンに専用の例外ハンドラが定義されていない限り，この例外処理ブロックで例外を処理します。

try 部の文が例外を生成した場合，ただちに実行が except 部に移行し，except 部の各例外処理文 (例外ハンドラ) の中から現在の例外に対応するハンドラが探されます。

アプリケーションは，例外に対応した例外ハンドラを探し出してそれを実行し，さらに例外オブジェクトを自動的に破棄します。実行は現在のブロックの最後まで続行されます。


Exception-handling statements
Exception-handling statements1062017

Section topics	参照

try..except ブロックの except 部の各文では，特定の例外を処理するために実行するコードを定義します。例外処理文の形式は次のとおりです。

on < 例外の種類 > do < 文 >;

Example1062018

たとえば，0 による除算に対してデフォルトの結果を返すような例外ハンドラを定義してみます。

function GetAverage(Sum, NumberOfItems: Integer): Integer;

begin

  try

    Result := Sum div NumberOfItems;	{通常の場合の処理}

  except

    on EDivByZero do Result := 0;	{必要なときだけ例外処理}

  end;

end;

この例のようにすれば，関数を呼び出すごとに 0 をチェックしなくて済みます。次に例外を使用しないで同じ関数を記述してみます。

function GetAverage(Sum, NumberOfItems: Integer): Integer;

begin

  if NumberOfItems <> 0 then	{常にチェックする}

    Result := Sum div NumberOfItems	{通常の計算を行う}

  else Result := 0;	{例外処理の場合}

end;

上に示した 2 つの関数は，例外を使用したプログラミングと例外を使用しないプログラミングの違いを浮き彫りにしています。これは単純な例でしたが，数百のステップを使用する複雑な計算の中で，1 つの不正な入力のためにステップのいずれかがエラーを起こすような場合もあります。

例外を使用すれば，アルゴリズムでは標準的な状況を想定すればよく，これからはずれる場合は例外として区別できます。例外を使用しないと，計算の各ステップごとにチェックして計算を続行できるかどうかを確認しなければなりません。


Using the exception instance
Using the exception instance1062019

Section topics	参照

通常，例外ハンドラで例外を処理するのに必要な情報は，例外の型だけです。したがって，on..do の後に続く文も例外の型に応じたものだけになります。しかし，例外インスタンス内の情報が必要になる場合もあります。

例外ハンドラにおいて例外インスタンスの特定の情報を入手するには，on..do の特別な形式を使用して例外インスタンスにアクセスします。この特別な形式では，インスタンスを保持する一時変数を利用します。

Example1062020

たとえば，フォームを 1 つ含む新規プロジェクトを作成して，このフォームにスクロールバーとボタンを追加します。ボタンをダブルクリックして次の行をクリックイベントハンドラに追加します。

ScrollBar1.Max := ScrollBar1.Min - 1;

この行は例外を生成します。スクロールバーの最大値は常に最小値よりも大きくなければならないからです。アプリケーションのデフォルト例外ハンドラでは，ダイアログボックスを開いて例外オブジェクトにメッセージを示します。このハンドラの例外処理をオーバーライドすると，独自の例外メッセージ文字列を示すメッセージボックスを作成できます。

try

  ScrollBar1.Max := ScrollBar1.Min - 1;

except

  on E: EInvalidOperation do

    MessageDlg('Ignoring exception: ' + E.Message, mtInformation, [mbOK], 0);

end;

一時変数 (この例では E) はコロンの後に指定された型 (この例では EInvalidOperation) の変数です。必要であれば as 演算子を使って例外を型キャストしてさらに限定した型にします。

メモ	一時例外オブジェクトは決して廃棄しないでください。例外オブジェクトは例外処理で自動的に廃棄されます。オブジェクトを手作業で廃棄すると，アプリケーションはオブジェクトを再び廃棄しようとするのでアクセス違反が発生します。


Scope of exception handlers
Scope of exception handlers1062021

Section topics	参照

すべてのブロックのすべての例外に例外ハンドラを用意する必要はありません。実際は，特定のブロック内の特に処理したい例外だけにハンドラを指定します。

ブロック内で処理できない例外が生成された場合，現在のブロックに未処理の例外を残して外側のブロック (封入ブロック，つまりこのブロックを呼び出したコード) に実行が戻ります。この移行は，例外を処理できるブロックのレベルに到達するか，アプリケーションの一番広いスコープに到達するまで，次々により広いスコープに戻る形で繰り返されます。

Providing default exception handlers1062022

専用のハンドラを指定していない例外を処理するために，デフォルト例外ハンドラを用意することができます。デフォルト例外ハンドラを提供するには，例外処理ブロックの except 部に else 部を追加します。

try

  { 文 }

except

  on ESomething do { 専用の例外処理コード };

  else { デフォルトの例外処理コード };

end;

デフォルトの例外処理を追加したブロックでは，あらゆる例外処理を扱うことになります。そのため，このブロックの外側にあるすべての例外処理は呼び出されなくなります。

注意	デフォルト例外ハンドラはすべての例外に対応してしまうので，なるべく使用しないでください。else を使用すると，正体が不明の例外も含めてすべての例外を処理してしまいます。通常，コードでは処理方法が明確にわかっている例外だけを処理するようにします。処理方法のわからない例外にはクリーンアップコードを実行し，その例外と処理方法についての情報を持っている別のコードに処理をまかせます。


Handling classes of exceptions
Handling classes of exceptions1062023

Section topics	参照

例外オブジェクトはオブジェクト階層の一部です。したがって，例外オブジェクトの派生元に当たる例外クラスにハンドラを指定すると，下位の階層のすべての部分にハンドラを指定できます。

Example1062024

次に，すべての整数演算例外を処理するハンドラの形式を示します。

try

  { 整数演算を行う文 }

except

  on EIntError do { 整数演算エラー汎用の処理 };

end;

汎用ハンドラを指定した場合も，個別の例外を処理する専用ハンドラを以前と同じように指定できます。ただし，個別の専用ハンドラは必ず汎用ハンドラの前に指定してください。アプリケーションはハンドラを配置順に検索し，最初に見つけたハンドラを実行するからです。

たとえば，次のブロックでは範囲エラー専用の処理とほかのすべての整数演算エラーの処理を指定しています。

try

  { 整数演算を行う文 }

except

  on ERangeError do { 範囲外エラー専用の処理 };

  on EIntError do { ほかの整数演算エラーの処理 };

end;

EIntError のハンドラを ERangeError のハンドラの前に記述すると，ERangeError の専用ハンドラまで実行が到達しません。


Reraising the exception
Reraising the exception1062025

Section topics	参照

ブロック内で例外をローカルに処理する場合，ローカルな処理を外側のブロック (封入ブロック) の処理に置き換えるのではなく，ローカルな処理を外側の処理に追加する形で行いたい場合があります。もちろん，ローカルハンドラで例外を処理して例外インスタンスを廃棄してしまえば，外側のブロックのハンドラの出番はありません。しかし，ローカルハンドラで例外を廃棄せず，外側のブロックのハンドラに対処させることもできます。

Example1062026

例外が発生したら，ユーザーに適切なメッセージを表示して，所定の処理を行うことにします。この場合は，メッセージを表示するローカルな例外ハンドラを宣言し，次に予約語 raise を記述します。これを例外の再生成といいます。次に例を示します。

try

  { 文 }

  try

    { 特別な文 }

  except

    on ESomething do

    begin

      { 特別な文だけに対する処理 }

      raise;	{例外を再生成する}

    end;

  end;

except

  on ESomething do ...;	{すべてに通用する処理}

end;

{文} の部分のコードで ESomething 例外が発生すると，外側の except 部のハンドラだけが実行されます。一方，{特別な文} の部分のコードで ESomething が発生すると，内側の except 部の処理が実行され，さらに外側の except 部の一般的な処理が実行されます。

例外を再生成すれば，既存のハンドラを使いながら個別の例外の処理を簡単に提供できます。


Handling component exceptions
Handling component exceptions1062027

Section topics	参照

Delphi のコンポーネントはエラーを通知するために例外を生成します。ほとんどのコンポーネント例外は，実行時エラーを発生するようなプログラミングエラーに起因します。コンポーネント例外の処理方法は RTL 例外の処理方法と同じです。

Example1062028

各コンポーネントに共通するエラーとして，インデックス付けされたプロパティの範囲エラーがあります。たとえば，リストボックスに 0～2 の範囲でインデックス付けされた 3 つの項目がある場合，アプリケーションで項目番号 3 を指定すると，リストボックスは範囲を超えたことを表す例外を生成します。

次に示すイベントハンドラには，リストボックスで無効なインデックスにアクセスしたことをユーザーに知らせるための例外ハンドラが含まれます。

procedure TForm1.Button1Click(Sender: TObject);

begin

  ListBox1.Items.Add('a string');	{ リストボックスに文字列を挿入する }

  ListBox1.Items.Add('another string');	{ 2 つめの文字列を追加し ...}

  ListBox1.Items.Add('still another string');	{... 3 つめの文字列を追加する }

  try

    Caption := ListBox1.Items[3];	{フォームのキャプションにリストボックスの 4 つめの文字列を設定する}

  except

    on EStringListError do

      MessageDlg('List box contains fewer than four strings', mtWarning, [mbOK], 0);

  end;

end;

ボタンを 1 回クリックしただけの状態では，リストボックスには 3 つの文字列しかないので，4 つめの文字列 (Items [3]) にアクセスすると例外を生成します。もう一度クリックすると，リストには文字列が追加されているので，例外は生成されなくなります。


Silent exceptions
Silent exceptions1062029

Section topics	参照

Delphi アプリケーションでは，コードで処理されないほとんどの例外は，例外オブジェクトのメッセージ文字列を示すメッセージボックスを表示して処理します。これに対してサイレント例外を定義すると，デフォルトとして，エラーメッセージを表示させないように指定できます。

サイレント例外は，例外を処理せずにハンドラの処理自体を中止するときに使用します。処理の中止は Break または Exit でブロックから抜けることに似ています。ただし，処理の中止では複数レベルにネストしたブロックから一気に抜けることができます。

すべてのサイレント例外は，標準例外型の EAbort 型から派生しています。Delphi アプリケーションのデフォルト例外ハンドラでは，EAbort から派生した例外についてだけは，エラーメッセージダイアログボックスを表示しません。

サイレント例外を生成するショートカットとして，手作業でオブジェクトを構築するかわりに，Abort 手続きを呼び出すこともできます。Abort は自動的に EAbort 例外を生成し，エラーメッセージを表示せずに現在の処理を終了します。

Example1062030

処理を中止する簡単な例を次に示します。空のリストボックスとボタンがあるフォームで，ボタンの OnClick イベントに次のコードを結び付けます。

procedure TForm1.Button1Click(Sender: TObject);

var

  I: Integer;

begin

  for I := 1 to 10 do	{10 回ループする}

  begin

    ListBox1.Items.Add(IntToStr(I));	{リストに数を追加する}

    if I = 7 then Abort;	{7 回目で中止する}

  end;

end;


Defining your own exceptions
Defining your own exceptions1062031

Section topics	参照

ランタイムライブラリや各種のコンポーネントで生成される例外からコードを保護することに加えて，同じメカニズムを使って独自の例外条件も管理できます。

コードで例外を使用するためには，以下の点を理解している必要があります。

例外オブジェクト型の宣言

例外の生成


Declaring an exception object type
Declaring an exception object type1062032

Section topics	参照

例外はオブジェクトなので，新しい種類の例外を定義するのは新しいオブジェクト型を宣言するのと同じように簡単です。あらゆるオブジェクトインスタンスを例外として生成できますが，標準の例外ハンドラで処理できるのは Exception から派生した例外だけです。

したがって，新しい種類の例外は Exception から派生させます。そうすれば，ブロックで生成した新しい例外が専用の例外ハンドラで処理されなくても，いずれかの標準のハンドラで処理できます。

Example1062033

たとえば，次に示す宣言を考えてみます。

type

  EMyException = class(Exception);

EMyException を生成した場合，この例外の専用ハンドラを指定していなくても Exception のハンドラ (またはデフォルトの例外ハンドラ) で処理できます。Exception の標準の処理では生成された例外の名前を表示するので，少なくとも新しい例外が生成されたことを確認できます。


Raising an exception
Raising an exception1062034

Section topics	参照

アプリケーションでエラーを通知するには例外を生成します。例外を生成するには，例外の型に属するインスタンスを構築し，raise 予約語を使用します。

例外を生成するには次のようにします。

予約語 raise に続けて例外オブジェクトのインスタンスを呼び出す

例外ハンドラで例外を処理した場合は，処理が終了するときに例外インスタンスは廃棄されます。したがって，手作業で例外インスタンスを廃棄する必要はありません。

Setting the exception address1062035

例外が発生すると，アプリケーションで例外を生成したアドレスが System ユニットの ExceptAddr 変数に代入されます。そのため，例外ハンドラの ExceptAddr を参照してエラーの発生場所をユーザーに知らせることもできます。ExceptAddr に値を指定して例外を生成することもできます。

例外のエラーアドレスを指定するには次のようにします。

予約語 at を例外インスタンスの後に追加し，さらに識別子などのアドレス式を続ける

Examples1062036

たとえば，次のように宣言します。

type

  EPasswordInvalid = class(Exception);

EPasswordInvalid のインスタンスによる例外生成を次のように呼び出して無効のパスワード例外をいつでも生成することができます。

if Password <> CorrectPassword then

  raise EPasswordInvalid.Create('Incorrect password entered');


See also1062037

Object Pascal のブロック

Object Pascal のユニット

コンポーネント開発者のためのオブジェクト指向プログラミング

コードエディタでのファイルの表示


Working with string lists
Working with string lists1074001

Section topics	参照

アプリケーションでは文字列のリストを頻繁に扱います。文字列のリストには，リストボックスやコンボボックスの項目，メモフィールドのテキストの行，画面用のフォントのリスト，タブコントロールのタブの名前，アウトラインの項目，文字列グリッドの行や列の項目などがあります。

これらのリストの用途はアプリケーションによってさまざまです。しかし，Delphi は文字列リストというオブジェクトをとおして，すべてのリストに共通なインターフェースを提供します。メモフィールドで編集した文字列をリストボックスの項目のリストとして使用するなど，文字列リスト間で相互に文字列を交換することもできます。

すでにオブジェクトインスペクタで文字列リストを使用したことがあるかもしれません。オブジェクトインスペクタの値列に (TStrings) と表示されているプロパティは，文字列リストです。(TStrings) をダブルクリックすると，文字列リストエディタ (［文字列リストの設定］ダイアログボックス) が表示され，このエディタで行の編集，追加，削除を行えます。

文字列リストは実行時にも操作できます。一般に，以下のような処理で文字列リストを扱います。

リスト内の文字列の操作

文字列リストの読み込みと保存

新しい文字列リストの作成

文字列リストへのオブジェクトの追加


Manipulating the strings in a list
Manipulating the strings in a list1074002

Section topics	参照

アプリケーションでは，既存の文字列リストにある文字列を操作するコードを記述することがよくあります。最も多いのは，アプリケーションのコンポーネントに文字列リストプロパティがあり，このプロパティを変更したり，このプロパティから文字列を取得する場合です。

一般に，以下のような操作があります。

リスト内の文字列をかぞえる

特定の文字列にアクセスする

文字列の位置を調べる

リストに文字列を追加する

リスト内の文字列を移動する

リストから文字列を削除する

文字列リスト全体をコピーする

リスト内の文字列を繰り返し処理する


Counting the strings in a list
Counting the strings in a list1074003

Section topics	参照

文字列リスト内の文字列の数を調べるには次のようにします。

Count プロパティを使用する

Count はリスト内の文字列の数を示す読み出し専用プロパティです。文字列リストのインデックスは 0 から始まるので，Count はリストの最後の文字列のインデックスよりも 1 つ多い値になります。

例

たとえば，アプリケーションの現在の画面用のフォントの数を調べるには，TScreen オブジェクトのフォントリスト Fonts の Count プロパティを読み出します。フォントリストは，サポートしているすべてのフォントの名前を示す文字列リストです。

FontCount := Screen.Fonts.Count;


Accessing a particular string
Accessing a particular string1074004

Section topics	参照

文字列リストには，Strings というインデックス付きのプロパティがあります。さまざまな目的のために，このプロパティを文字列の配列のように扱うことができます。たとえば，リストの最初の文字列は Strings[0] になります。しかしここで，Strings プロパティは文字列リストで最も頻繁にアクセスする部分なので，リストのデフォルトプロパティになっています。そのため，Strings 識別子を省略して文字列リスト自体をインデックス付きの文字列配列として扱えます。

文字列リストの特定の文字列にアクセスするには次のようにします。

リスト内の位置，つまりインデックスを使用して文字列を参照する
文字列のインデックス番号は 0 から始まるので，リストに文字列が 3 つある場合，そのインデックスは 0～2 になります。

インデックスの最大値を調べるには次のようにします。

Count プロパティを調べる

有効なインデックスの範囲を超えて文字列にアクセスしようとすると，文字列リストは例外を生成します。

例

Strings 識別子を使用したコードと省略したコードの例を次に示します。2 つのコードはいずれもメモコンポーネントの最初のテキスト行を設定します。

Memo1.Lines.Strings[0] := 'This is the first line.';

Memo1.Lines[0] := 'This is the first line.';


Finding the position of a string
Finding the position of a string1074005

Section topics	参照

文字列リストで文字列の位置を確認したい場合があります。また，文字列リストに文字列があるかどうかを確認する場合もあります。

文字列リストで文字列を探すには次のようにします。

文字列リストの IndexOf メソッドを使用する

IndexOf はパラメータとして文字列を受け取り，リスト内で一致する文字列のインデックスを返します。文字列リストに一致する文字列がなければ -1 を返します。

IndexOf は文字列全体を比較する場合にのみ使用できます。つまり，このメソッドに渡した文字列全体と一致する文字列をリスト内で探します。したがって，部分文字列の一致を検索する場合には使用できません。たとえば，特定の文字列を含む文字列がリスト内にあるかどうかを調べる場合などは，独自のコードでリストの個々の文字列を比較しなければなりません。

例

IndexOf を使用して，ファイルリストボックスのファイルリストに特定のファイル名があるかどうかを調べる例を次に示します。

if FileListBox1.Items.IndexOf('WIN.INI') > -1 then
{カレントディレクトリが Windows の場合};


Adding a string to a list
Adding a string to a list1074006

Section topics	参照

文字列リストに文字列を追加するときは，リストの最後に追加する場合とリストの途中に挿入する場合とを区別します。

リストの最後に文字列を追加するには次のようにします。

Add メソッドを呼び出して，追加する文字列をパラメータとして渡す
追加した文字列はリストの最後の文字列になります。

リストの中に文字列を挿入するには次のようにします。

Insert メソッドを呼び出して，文字列の挿入先のインデックスと文字列自体の 2 つをパラメータとして渡す

例

たとえば文字列 'Three' を TString オブジェクト Nums のリストの 3 番目に挿入するには，Nums.Insert(2, 'Three'); とします。この場合，リストに少なくとも 2 つの文字列がないと範囲を超えたことを示す例外が生成されます。


Moving a string within a list
Moving a string within a list1074007

Section topics	参照

リストをソートする場合など，文字列リスト内で文字列をほかの位置に移動することがあります。文字列に関連付けられたオブジェクトがあれば，文字列とともに移動します。

リスト内で文字列を移動するには次のようにします。

Move メソッドを呼び出して文字列の移動前のインデックスと移動後のインデックスの 2 つのパラメータを渡す

たとえば，リストの 3 番目の文字列を 5 番目の位置に移動するには，Move(2,4) とします。


Deleting a string from a list
Deleting a string from a list1074008

Section topics	参照

文字列リストから文字列を削除するには次のようにします。

文字列リストの Delete メソッドを呼び出して，削除する文字列のインデックスを渡す
削除する文字列のインデックスがわからない場合は，IndexOf メソッドで調べられます。

文字列リストのすべての文字列を削除するには次のようにします。

Clear メソッドを使用する

例

リスト内の文字列の位置を IndexOf で探して，その文字列を削除する例を次に示します。

with ListBox1.Items do

begin

  if IndexOf('bureaucracy') > -1 then

     Delete(IndexOf('bureaucracy'));

end;


Copying a complete string list
Copying a complete string list1074009

Section topics	参照

ある文字列リストから別のリストへ文字列のリストをコピーするには次のようにします。

ソースリストをターゲットリストに代入する

代入元と代入先のコンポーネントの種類が異なる場合も，代入先に文字列リストが存在しない場合も，リストは正しくコピーされます。

リスト間で文字列をコピーすると，ターゲットリストの文字列は上書きされます。リストの最後に別のリストの文字列を追加する場合は，AddStrings メソッドを呼び出し，追加する文字列のリストをパラメータとして渡します。

例

コンボボックスからアウトラインへ項目をコピーする例を次に示します。

Outline1.Lines := ComboBox1.Items;

コンボボックスのすべての項目をアウトラインの最後に追加する例を次に示します。

Outline1.AddStrings(ComboBox1.Items);


Iterating the strings in a list
Iterating the strings in a list1074010

Section topics	参照

リスト内の各文字列に同じ操作を繰り返し適用する場合もよくあります。たとえば，特定の部分文字列を検索する場合や各文字列の大文字小文字を変更する場合です。

リストの各文字列を繰り返し処理するには次のようにします。

for ループで Integer 型のインデックスを使用する。このループでは，0 からリストの文字列数より 1 つ少ない数 (Count-1) までのインデックスを対象にする

ループ内では各文字列にアクセスし，必要な操作を行います。

例

ボタンクリックに応じてリストボックスの文字列を繰り返し処理し，各文字列を大文字だけに変換するループの例を次に示します。

procedure TForm1.Button1Click(Sender: TObject);

var

   Index: Integer;

begin

  for Index := 0 to ListBox1.Items.Count - 1 do

     ListBox1.Items[Index] := UpperCase(ListBox1.Items[Index]);

end;


Loading and saving string lists
Loading and saving string lists1074011

Section topics	参照

Delphi の文字列リストは，簡単にテキストファイルに格納して同じリストや別のリストに読み込めます。文字列リストオブジェクトは，格納するメソッドと読み込むメソッドの両方を持っています。たとえば読み込み用のメソッドは，メモコンポーネントで単純なテキストエディタを作成する場合に，ファイルの読み込みに使用できます (「子フォームへの文書の挿入」を参照)。一方，文字列リストを格納するメソッドでは，リストボックスやアウトライン全体の項目リストを保存できます。

テキストファイルに文字列リストを格納するには次のようにします。

SaveToFile メソッドを呼び出して保存先のテキストファイルの名前を渡す
SaveToFile では保存先のファイルがない場合はこれを自動的に作成します。保存先のファイルがある場合は，その現在の内容を文字列リストの文字列で上書きします。

例

C ドライブの Windows ディレクトリからメモフィールドへ WIN.INI ファイルを読み込み，WIN.BAK というバックアップコピーを作成する例を次に示します。

procedure TForm1.FormCreate(Sender: TObject);

var

   FileName: string;	{ファイル名の格納域}

begin

   FileName := 'C:\WINDOWS\WIN.INI';	{ファイル名を設定する}

  with Memo1.Lines do

   begin

    LoadFromFile(FileName);	{ファイルから読み込む}

    SaveToFile(ChangeFileExt(FileName, '.BAK'));	{バックアップファイルへ保存する}

  end;

end;


Creating a new string list
Creating a new string list1074012

Section topics	参照

使用する文字列リストのほとんどはコンポーネントの一部なので，通常は文字列リストを独自に構築する必要はありません。しかし，コンポーネントと関連付けられていない独立した文字列リストを作成することもできます。たとえば，アプリケーションで参照テーブルの文字列のリストを保持する場合があります。

独自の文字列リストを作成する場合に最も重要なことは，文字列リストが不要になったら廃棄することです。廃棄には 2 つの方法があります。文字列リストの作成，使用，廃棄のすべてを単一のルーチンで行う方法と，作成した文字列リストを継続的に使用し，アプリケーションの終了前に廃棄する方法です。

文字列リストを作成して管理する方法は，長期的に使用するか短期的に使用するかで異なります。


Short-term string lists
Short-term string lists1074013

Section topics	参照

1 つのルーチンの存続期間の中でのみ文字列リストを使用する場合は，作成，使用，廃棄のすべてを一箇所で行います。これは，文字列リストオブジェクトを使用する最も安全な方法です。

メモリは文字列リストオブジェクト自体と各文字列に割り当てられます。したがって，この割り当てを try..finally ブロックで保護し，例外が生じた場合でもオブジェクトのメモリを解放できるようにします。

短期的な文字列リストの使用方法の概略は，次のとおりです。

1.	文字列リストオブジェクトを作成します。

2.	try..finally ブロックで文字列リストを使用します。

3.	finally 部で文字列リストオブジェクトを解放します。

例

ボタンクリックに応答して，文字列リストを作成し，使用後に破棄するイベントハンドラを次に示します。

procedure TForm1.Button1Click(Sender: TObject);

var

   TempList: TStrings;	{リストを宣言する}

begin

  TempList := TStringList.Create;	{リストオブジェクトを作成する}

  try

     { 文字列リストを使用する }

  finally

     TempList.Free;	{リストオブジェクトを破棄する}

  end;

end;


Long-term string lists
Long-term string lists1074014

Section topics	参照

アプリケーションの実行中に随時使用できる文字列リストを作成するには，アプリケーションの実行開始時点で文字列リストを作成し，アプリケーションの終了前に廃棄します。

実行中に随時使用できる文字列リストを作成する方法は，次のとおりです。

1.	アプリケーションのメインフォームオブジェクトに TStrings 型の項目を追加して名前を付けます。

2.	メインフォームの OnCreate イベントのハンドラを作成します。実行時には，この作成イベントハンドラが実行された後で画面にフォームが表示されます。

3.	作成イベントハンドラ内で，文字列リストオブジェクトを作成します。

4.	メインフォームの OnDestroy イベントのハンドラを作成します。この廃棄イベントハンドラは，メインフォームが画面から消えた直後，アプリケーションの実行の終了前に実行されます。

この文字列リストは，ほかのイベントハンドラからも手順の 1 で宣言した名前によってアクセスできます。

例

次に示すのは ClickList という文字列リストにデータを追加する例です。ユーザーがマウスボタンをクリックするたびに，メインフォームの FormMouseDown ハンドラは，このリストに文字列を追加します。アプリケーションの終了時には，このリストをファイルへ書き出した後で廃棄します。

unit Unit1;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs;

type

   TForm1 = class(TForm)

    procedure FormCreate(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

       Shift: TShiftState; X, Y: Integer);

  private

    { Private 宣言 }

  public

    { Public 宣言 }

    ClickList: TStrings;	{リストを宣言する}

  end;

var

   Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

begin

   ClickList := TStringList.Create;	{リストを作成する}

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

  ClickList.SaveToFile(ChangeFileExt(Application.ExeName, '.LOG'));
{リストを保存する}

  ClickList.Free;	{リストオブジェクトを破棄する}

end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

   Shift: TShiftState; X, Y: Integer);

begin

   ClickList.Add(Format('Click at (%d, %d)', [X, Y]));
{リストに文字列を追加する}

end;

end.


Adding objects to a string list
Adding objects to a string list1074015

Section topics	参照

文字列リストは，文字列のリストだけでなく，オブジェクトのリストも持つことができます。文字列のリストは Strings プロパティに格納され，オブジェクトのリストは Objects プロパティに格納されます。Objects プロパティは，Strings プロパティと同じようにインデックスが付いていますが，文字列ではなくオブジェクトのリストです。

リストで文字列だけを使用するのであれば，オブジェクトはなくてもかまいません。オブジェクトに特にアクセスしない限り，オブジェクトは使用されないからです。また，Objects プロパティにどのようなオブジェクトを代入したとしても，文字列の方には影響しません。Delphi は情報を保持するだけです。この情報は開発者が必要に応じて操作します。

メモ	文字列リストには，オブジェクトを持つ意味がないためにオブジェクトを追加しても無視するものがあります。たとえば，メモの行を表す文字列リストは，オブジェクトを追加しても格納しません。これとは逆に，標準的にオブジェクトを使用する文字列リストもあります。たとえば，ノートブックのページなどです。Notebook コンポーネントは，文字列リスト Pages をページの名前とページを表すオブジェクトの両方を格納するために使用します。

Objects プロパティにはあらゆるオブジェクトを代入できます。一般的に多いのは，ビットマップと文字列を関連付けてオーナー描画コントロールで使用する例です。この場合，文字列リストでは文字列とオブジェクトが対になって動作することを忘れてはなりません。つまり，文字列ごとに関連付けられたオブジェクトがあるということです。ただし，デフォルトではオブジェクトは nil です。

なお，文字列リストは文字列リストに関連付けられたオブジェクトを所有するわけではありません。つまり，文字列リストオブジェクトを廃棄しても，文字列と関連付けられたオブジェクトは廃棄されません。


Operating on objects in a string list
Operating on objects in a string list1074016

Section topics	参照

文字列リストの各文字列に対する操作と，文字列と関連付けられた各オブジェクトに対する操作は似ています。たとえば，特定のオブジェクトを使用するにはインデックスを付けて Objects プロパティにアクセスします。これは，文字列を使用するために Strings プロパティにアクセスする場合と同じです。違う点は，識別子名の Objects を省略できないことだけです。Strings は文字列リストのデフォルトプロパティなので，識別子名を省略できます。

次の表に，文字列リストの文字列とオブジェクトのプロパティとメソッドをまとめます。

処理	文字列の場合	オブジェクトの場合
項目へのアクセス	Strings プロパティ	Objects プロパティ
項目の追加	Add メソッド	AddObject メソッド
項目の挿入	Insert メソッド	InsertObject メソッド
項目の検索	IndexOf メソッド	IndexOfObject メソッド
Delete，Clear，Move などのメソッドは，項目全体を対象とします。つまり，文字列を削除すると文字列とともに対応するオブジェクトも削除されます。一方，LoadFromFile メソッドと SaveToFile メソッドはテキストファイルを扱うので，文字列だけを対象とします。

関連付けられたオブジェクトへのアクセス

文字列リストに関連付けられたオブジェクトにアクセスする方法は，文字列にアクセスする方法と同じです。たとえば，文字列リストの最初の文字列を取得するには，文字列リストの Strings プロパティのインデックス 0 にある Strings[0] にアクセスします。同じように，この文字列に対応するオブジェクトを取得するには Objects[0] にアクセスします。

関連付けられたオブジェクトの追加

オブジェクトを既存の文字列と関連付けるには，文字列と対応するインデックス位置の Objects プロパティにオブジェクトを代入します。たとえば，Fruits という文字列リストに文字列 'apple' があり，これに AppleBitmap というビットマップを関連付ける場合は，次の代入文を使用します。

with Fruits do Objects[IndexOf('apple')] := AppleBitmap;

文字列とオブジェクトを同時に追加するには，文字列リストの AddObject メソッドを呼び出します。Add メソッドは文字列だけを追加する場合に使用します。AddObject には，文字列とオブジェクトを 2 つのパラメータとして渡します。次に例を示します。

Fruits.AddObject('apple', AppleBitmap);

対となる文字列がなければオブジェクトを追加できないことに注意してください。


See also1074017

オブジェクトとは

オーナー描画コントロールの作成


Using Windows common dialogs
Using Windows common dialogs1055001

Section topics	参照

Windows のアプリケーションでは，操作環境に組み込まれたダイアログボックスを使って，ファイルを開く，ファイルの保存 (画像ファイルを開いたり保存したりする特別なダイアログボックスを含む)，フォントや色の選択，情報の印刷，あるいは情報の検索や置換などを行います。これらのダイアログボックスはまとめてWindows コモンダイアログボックスとして知られています。コンポーネントパレットの［Dialog］ページにあるコンポーネントを使うと，Delphi のアプリケーションでコモンダイアログボックスを利用できます。

この章では，コモンダイアログボックスのいくつかの使い方についての例を示します。


Adding a common dialog box to a project
Adding a common dialog box to a project1055002

Section topics	参照

プロジェクトにコモンダイアログボックスを追加する方法は次のとおりです。

1.	フォームにコモンダイアログコンポーネントを置きます。
設計時には，コンポーネントのアイコンが表示されるだけですが，実行時に呼び出されるとダイアログボックスが表示されます。

2.	ダイアログボックスに，タイトル，ファイル名フィルターなどのプロパティを設定します。

3.	実行時には，ダイアログボックスコンポーネントの Execute メソッドを呼び出します。


Executing common dialog boxes
Executing common dialog boxes1055003

Section topics	参照

コモンダイアログボックスに関して忘れてはならない重要なことは，コモンダイアログボックス自体がファイルを開いたり色を変更したりする操作を実行するのではないということです。このような操作は，アプリケーションが責任を持ちます。コモンダイアログボックスは，ファイル名の選択や色の選択のような共通操作のための共通インターフェースを提供します。アプリケーションはこの情報を使用して適切な操作をします。

コモンダイアログボックスには，「オプション」と「サマリ」の 2 種類があります。オプションダイアログボックスはユーザーにいくつかのオプションを提供し，個々のプロパティでそれぞれのオプションを返します。オプションダイアログボックスの例としては，［印刷］があります。サマリダイアログボックスは，ユーザーが選択したすべてのオプションを組み合わせて 1 つのサマリプロパティにまとめます。サマリダイアログボックスの例としては，［フォントの指定］や［色の設定］ダイアログボックスがあります。

実行時にコモンダイアログボックスを使う手順は次のとおりです。

1.	サマリプロパティの初期値 (ファイル名，色，フォントなど) または初期オプションを設定します。

2.	ダイアログボックスコンポーネントの Execute メソッドを呼び出します。
Execute はダイアログボックスを開き，ユーザーがダイアログボックスを閉じたときに論理値を返します。ユーザーが［OK］を選択して，ダイアログボックスでの変更を確定した場合は，Execute は True を返します。ユーザーが［キャンセル］を選択して，変更や保存をせずにダイアログボックスを閉じた場合は，Execute は False を返します。

3.	ユーザーがダイアログボックスの設定を取り消さない場合，サマリプロパティの値またはオプションの設定を読み出して利用します。

次の節では，Windows コモンダイアログボックスを使った処理の例について説明します。例として示されるコードは DEMOS\DOC\TEXTEDIT にある MDI テキストエディタアプリケーションです。


Selecting files to open
Selecting files to open1055004

Section topics	参照

MDI アプリケーションでは，［ファイルを開く］ダイアログボックスとのやり取りによって子ウィンドウに既存のファイルを開き，ファイルを読み込む提供します。OpenDialog コンポーネントのいくつかのプロパティに初期値を設定して数行のコードを記述すれば，ほかの Windows アプリケーションと同じインターフェースをユーザーに提供できます。ユーザーは利用可能なファイルのリストの表示と，開くファイルの選択が簡単にできるようになります。


Specifying file filters
Specifying file filters1055005

Section topics	参照

［File｜Open］ダイアログボックスの［ファイルの種類］リストボックスでは，このダイアログボックスに表示するファイルの種類をファイル拡張子で指定します。このファイル拡張子を「フィルタ」といいます。拡張子に応じた一定パターンのファイルをアプリケーションで使う場合，カスタムフィルタを標準の［File｜Open］ダイアログボックスに追加できます。

ファイル名フィルタのリストを作成する手順は次のとおりです。

1.	オブジェクトインスペクタで OpenDialog コンポーネントの Filter プロパティを選択します。

2.	［...］ボタンをクリックするか値列をダブルクリックして，フィルタエディタを開きます。

3.	フィルタをかけるファイルの種類ごとに，フィルタ名とフィルタマスクを入力します。

ファイルフィルタの作成についての詳細は，オンラインヘルプの「フィルタエディタ」と「フィルタプロパティ」を参照してください。

Options プロパティを使って，読み出し専用ファイルの処理方法など，ダイアログボックスでのその他の動作を指定することもできます。


Opening an existing file
Opening an existing file1055006

Section topics	参照

一般にアプリケーションではメニューコマンドに応答してファイルを開きますが，ほかの手順でファイルを開くこともあります。ただし，全体的な処理は同じです。メニューコマンドに応じて，アプリケーションは次のように処理します。

1.	ユーザーに［File｜Open］のダイアログボックスでファイル名を選択させます。

2.	選択されたファイル名を読み出し，そのファイルを開きます。

このサンプルでは，フレームフォームと子フォームの両方の［File｜Open］のクリックイベントに対するイベントハンドラを記述します。［File｜New］のクリックイベントに対するイベントハンドラの場合と同じように，子フォームのハンドラはフレームフォームのハンドラを呼び出すだけです。次に，FrameForm の［File｜Open］のイベントハンドラが，子フォームに追加される Open メソッドを呼び出します。

procedure TFrameForm.Open1Click(Sender: TObject);

begin

  if OpenFileDialog.Execute then	{ファイルが選択されると，}

  with TEditForm.Create(Self) do	{新しい子ウィンドウを作成し，}

    Open(OpenFileDialog.FileName);	{ファイルを開く}

end;

procedure TEditForm.Open1Click(Sender: TObject);

begin

  FrameForm.Open1Click(Sender);	 {フレームフォームのハンドラを呼び出す}

end;

［File｜Open］のクリックのイベントハンドラコードは，［ファイルを開く］ダイアログボックスを実行します。ユーザーが開くファイルを選択すると，Execute が True を返し，残りのコードが実行されます。［ファイルを開く］ダイアログボックスでユーザーが指定したファイル名は子フォームの Open メソッドに渡されます。


Setting the cursor position upon opening a text file
Setting the cursor position upon opening a text file1055007

Section topics	参照

メソッドをフォームに追加しなければならない場合がよくあります。その 1 つが，ある種のフォームに機能を追加する場合です。

メソッドをフォームに追加する手順は次のとおりです。

1.	フォームのクラスにメソッドの宣言を追加します。

2.	フォームのユニットの implementation 部にメソッドを実装します。

メソッドの記述についての詳細は，「手続きと関数」を参照してください。

次の例は，子フォームに Open メソッドを追加するサンプルテキストエディタのアプリケーションです。カーソルは開かれたときに文書の先頭に表示されるようになります。MDIEdit ユニットの interface 部にある TEditForm 型宣言の public 部に，次の行を追加します。

procedure Open(const FileName: string);

implementation 部に はOpen メソッドを記述します。

procedure TEditForm.Open(const FileName: string);

begin

  PathName := FileName;	{フォーム変数にパラメータを割り当てる}

  Editor.Lines.LoadFromFile(PathName);	{指定されたファイルを読み込む}

  Editor.SelStart := 0;	{カーソルをファイルの先頭に移動する}

  Caption := ExtractFileName(PathName);	{フォームのキャプションにファイル名を表示する}

  Editor.Modified := False;	{Modified フラグをリセットする}

end;

エディタがファイルを読み込むと，Open メソッドはエディタの SelStart プロパティの値を 0 にリセットします。SelStart プロパティは選択されているテキストの開始位置を表しますが，選択されているテキストがなければ現在のカーソル位置を表します。デフォルトでは，エディタがファイルの内容を読み込むと，SelStart は最終行の末尾を表します。SelStart に 0 を設定すれば，カーソルはファイルの先頭に表示されます。

エディタの Modified プロパティに False を設定すると，ユーザーがテキストファイルに対して変更を行ったかどうかを取得できます。変更があると，Modified は True になります。これにより，アプリケーションを終了する前に，変更されたファイルの保存をユーザーに促せるようになります。


Saving files
Saving files1055008

Section topics	参照

ユーザーが作成した新規ファイルや，変更した既存のファイルは保存できなければなりません。アプリケーションで，既存のファイルと新規ファイル (名前の付いていないファイル) の両方を保存できるようにする必要があります。

このサンプルでは，以下の 2 つのイベントハンドラを使ってファイルを保存します。

Save1Click (ユーザーが［File｜Save］を選択したときに呼び出される)

SaveaAs1Click (ユーザーが［File｜Save as］を選択したときに呼び出される)


Saving existing files
Saving existing files1055009

Section topics	参照

保存のもっともわかりやすい例として，既存のファイルの再保存があります。ユーザーが［File｜Save］を選択した場合，アプリケーションは読み込んだファイルを元の場所に書き込めます。問題が起こるのは，ユーザーが名前を付けずに新規ファイルを保存しようとした場合だけです。したがって，保存前にこのような操作を中止させなければなりません。

サンプルのテキストエディタアプリケーションでファイルを保存するには，エディタコンポーネントの Lines プロパティの SaveToFile を呼び出します。エディタは文字列リストオブジェクトに行を格納します。文字列リストには，ファイルを保存するための仕組みが組み込まれています。文字列リストとファイルについての詳細は，「文字列リストの読み込みと保存」を参照してください。

この例は，子フォームの［File｜Save］メニューコマンドの OnClick イベントに次のハンドラを結び付けているサンプルアプリケーションです。

procedure TEditForm.Save1Click(Sender: TObject);

begin

  if PathName = DefaultFileName then	{ファイルに名前が付いていない場合には，}

    SaveAs1Click(Sender)	{ファイルの名前を選択する}

  else	{それ以外の場合は}

  begin

    Editor.Lines.SaveToFile(PathName);	{指定された名前でファイルを保存する}

    Editor.Modified := False;	{Modified フラグをリセットする}

  end;

end;

Save1Click は PathName がデフォルト以外の値になっているかを調べて，ファイルが以前に保存されているかどうかを確認します。アプリケーションでは，ユーザーが既存のファイルを開いた場合に PathName に値が割り当てられます。それ以外の場合は，PathName はデフォルトの名前を保持します。ファイルにデフォルトの名前が付いたままの場合，Save1Click はSaveAs1Click を呼び出してそのファイルの名前を取得します (SaveAs1Click は次の節で記述します)。ファイルに名前が付いていれば，Save1Click はエディタの内容をそのファイルに書き込み，Modified フラグをリセットします。


Saving a new or unnamed file
Saving a new or unnamed file1055010

Section topics	参照

ファイルを初めて保存する場合 (または既存のファイルを別のパスで保存する場合)，ファイル名を指定するようにアプリケーションからユーザーに促さなければなりません。そのために，［ファイル名を付けて保存］ダイアログボックスが使われます。

この例のテキストエディタアプリケーションには，SaveFileDialog という名前の［ファイル名を付けて保存］ダイアログボックスがあります。以下のイベントハンドラは，EditForm の［File｜Save as］のクリックイベントに結び付けられます。

procedure TEditForm.SaveAs1Click(Sender: TObject);

begin

  SaveFileDialog.FileName := PathName;	{サマリプロパティを設定する}

  if SaveFileDialog.Execute then	{名前を選択するが，}

  begin	{［OK］の場合だけその名前を使う}

    FileName := SaveFileDialog.FileName;	{サマリプロパティの値をコピーする}

    Caption := ExtractFileName(FileName);	{キャプションに名前の部分だけ表示する}

    Save1Click(Sender);	{ファイルを保存する}

  end;

end;

ユーザーが［名前を付けて保存］を選択したときにファイルにすでに名前が付いている場合，SaveAs1Click は［ファイル名を付けて保存］ダイアログボックスの［ファイル名(N)］編集ボックスに既存のファイル名を表示します。それ以外の場合は，ダイアログボックスの Filters プロパティに対応する情報が表示されます。

メモ	ユーザーはファイル名を入力しなければなりません。ファイル名を入力しないと，ユーザが［OK］を選択しても［ファイル名を付けて保存］ダイアログボックスは閉じません。これは，このダイアログボックスの仕様です。イベントハンドラのコードでそのように動作させているのではありません。

この時点で，アプリケーションでは新規ファイルでも既存のファイルでも保存できます。保存のメソッドが互いを呼び出していることに注意してください。名前の付いていないファイルを保存するのは，実際には［名前を付けて保存］です。ファイル名を設定すると，［名前を付けて保存］は単に［保存］と同じになります。


Creating a backup file
Creating a backup file1055011

Section topics	参照

新バージョンのファイルを保存する前に元のファイルのバックアップコピーを作成するようにした方がよいでしょう。バックアップの作成機能は，数行の Object Pascal コードを記述するだけで，ファイル保存のメソッドに追加できます。

保存時にバックアップファイルを作成する手順は次のとおりです。

1.	既存のバックアップファイルを削除します。

2.	既存のファイルの名前を変更してバックアップファイルの名前にします (通常は拡張子を変更します)。

3.	変更した既存のファイルを元のファイル名で保存します。

たとえば，次に示す数行を既存の Save1Click メソッドに追加して，保存時にバックアップファイルを作成するようにします。

procedure TEditForm.Save1Click(Sender: TObject);

var

  BackupFileName: string;	{バックアップファイル名の変数}

const

  BackupExt = '.BAK';	{バックアップファイルの拡張子を定義する}

begin

  if PathName = DefaultFileName then

     SaveAs1Click(Sender)

  else

  begin

    BackupFileName := ChangeFileExt(PathName, BackupExt);
{バックアップファイルの名前を作成する}

    DeleteFile(BackupFileName);	{既存のバックアップファイルを削除する}

    RenameFile(PathName, BackupFileName);
{元のファイルの名前を変更してバックアップファイルの名前にし，}

    Editor.Lines.SaveToFile(PathName);	{元の名前で保存する}

    Editor.Modified := False;

  end;

end;

Delphi 自体も含め，多くのアプリケーションでは，単に .BAK などの標準拡張子で置き換えるのではなく既存のファイル名拡張子を変更します。この機能は簡単にアプリケーションに追加できます。


Printing text
Printing text1055012

Section topics	参照

印刷は完全にアプリケーションによって制御されます。Windows には，プリンタを設定し，共通の印刷オプションをユーザーに提供するためのコモンダイアログボックスがあります。ただし，このようなオプションに応答して，印刷データをプリンタに送るのはアプリケーションの責任です。

Delphi には，プリンタのほとんどの動作がカプセル化された Printer オブジェクトがあります。この Printer オブジェクトを使用すると，印刷が簡単にできます。

Printer オブジェクトを使う手順は次のとおりです。

1.	プリンタへのアクセスが必要なユニットの uses 節に Printers ユニットを追加します。

2.	Printer オブジェクトの Canvas プロパティに，テキストまたはグラフィックを書き込みます。


Setting up the printer
Setting up the printer1055013

Section topics	参照

［プリンタの設定］ダイアログボックスは Windows のコモンダイアログボックスの 1 つです。ただし，ほかのコモンダイアログボックスの場合とは違って，このダイアログボックスとアプリケーションの間にはやり取りがほとんどありません。［プリンタの設定］ダイアログボックスの場合は Windows の環境設定ファイルとの間で設定を直接に参照し合うため，プリンタの設定は Windows 自体が処理することになります。

プリンタ設定機能をアプリケーションに追加する手順は次のとおりです。

1.	フォームに PrinterSetupDialog コンポーネントを入れます。

2.	［プリンタの設定］ダイアログボックスを実行します。以下に一例を示します。

PrinterSetupDialog1.Execute;

ChangeDefault は，実行時アプリケーションのダイアログボックスとやり取りする［プリンタの設定］ダイアログボックスコンポーネントが設計時に使用できる唯一のプロパティです。ユーザーが別のプリンタの設定を選択すると，このプロパティの実行時の値は True に変わります。

この場合，Execute の呼び出し結果を確認する必要はありません。ユーザーがダイアログボックスの設定を確定するか取り消すかに基づく何か別の処理を，アプリケーションが行うことがないからです。


Printing the text
Printing the text1055014

Section topics	参照

通常，Windows で印刷をする場合は，グラフィック表現のデータをプリンタの描画イメージとして送ります。同じ方法でテキストをグラフィックとしてプリンタに送ることもできますが，Delphi にはテキストを簡単に印刷する方法があります。

プリケーションからテキストを印刷する手順は次のとおりです。

1.	フォームに PrintDialog コンポーネントを入れます。

2.	実行時に［印刷］ダイアログボックスを表示して，ユーザーが印刷オプションを設定できるようにします。

3.	テキストをプリンタに送ります。


Printing rich text
Printing rich text1055015

Section topics	参照

このテキストエディタの例で，エディタとして書式付きテキストエディタを使っていた場合，その内容は簡単に印刷できます。

書式付きテキストエディタの内容を印刷するには次のようにします。

そのエディタコンポーネントの Print メソッドを呼び出します。

Windows の書式付きテキストエディタは，Delphi の Printer オブジェクトをまったく経由しないで Windows のデフォルトのプリンタに直接テキストを送れますが，テキストのすべての書式とワードラップを表すことができます。Print メソッドはパラメータとして 1 つの文字列を受け取り，これが文書ファイル名としてキャプションに使われます。

この例では，印刷するファイル名として PathName を使っています。子ウィンドウで［File｜Print］メニューコマンドに次のハンドラを結び付けます。

procedure TEditForm.Print1Click(Sender: TObject);

begin

  if PrintDialog1.Execute then	{［印刷］ダイアログボックスを表示する}

    Editor.Print(PathName);
{書式付きテキストエディタにその内容を印刷するよう指示する}

end;

この印刷のメソッドでは，［印刷］ダイアログボックスのすべてのオプションが完全に無視されます。しかし，このダイアログボックスで別のプリンタを選択したり，印刷を中止したりすることはできます。

次の節では，プリンタに直接テキストを送る方法について説明します。


Using the printer as a text device
Using the printer as a text device1055016

Section topics	参照

Windows の標準印刷インターフェースが使えるだけでなく，Delphi ではプリンタを標準テキストファイルデバイスとして割り当てることができます。これにより，テキストファイルに書き込むのと同じようにプリンタに文字列を書き込むことができます。このような印刷は高度なものではなく，基本的なテキスト印刷を処理する方法として簡単にできます。

プリンタをテキストファイルデバイスとして使う手順は次のとおりです。

1.	テキストファイル変数をプリンタに割り当てます。

2.	プリンタを書き込み用にテキストファイルとして開きます。

3.	文字列をファイルに書き込みます。

4.	ファイルを閉じます。

Delphi のランタイムライブラリには，テキストファイル出力のための標準手続きがいくつかあります。表にもっともよく使う手続きを示します。

ルーチン	用途
Assign	テキストファイル変数をディスクファイルに関連付ける
AssignPrn	テキストファイル変数をプリンタデバイスに関連付ける。Assign を呼び出してテキストファイルをディスクのファイルに関連付けるのに似ている
CloseFile	Reset または Rewrite で開いたファイルを閉じる
Rewrite	出力用にテキストファイルを開く
Write	データをテキストファイルに書き込む
Writeln	データをテキストファイルに書き込み，その後に改行を入れる
プリンタをテキストファイルデバイスとして使う手順に従って，［File｜Print］メニュー項目の OnClick イベントに対して次のようなハンドラを記述します。

procedure TEditForm.Print1Click(Sender: TObject);

var

  Line: Integer;	{行カウンタを宣言する}

  PrintText: TextFile;	{テキストファイル変数を宣言する}

begin

  if PrintDialog1.Execute then

  begin

    AssignPrn(PrintText);	{テキストファイルをプリンタデバイスに関連付ける}

    Rewrite(PrintText);	{出力ファイルを作成して開く}

    try

      for Line := 0 to Editor.Lines.Count - 1 do	{行を繰り返す}

        Writeln(PrintText, Editor.Lines[Line]);	{各行をプリンタに書き込む}

    finally

      CloseFile(PrintText);	{終わったら出力ファイルを閉じる}

    end;

  end;

end;

ファイル書き込みのコードを囲む形で try..finally ブロックを使っていることに注意してください。finally の部分があるため，プリンタへの書き込みで例外が発生してもファイルは必ず閉じます。


Setting the printer font
Setting the printer font1055017

Section topics	参照

アプリケーションでプリンタをテキストデバイスとして使うと，テキストはプリンタのデフォルトのフォント，つまりシステムフォントで印刷されますが別のフォントを設定することもできます。

プリンタのフォントは Printer オブジェクトの Canvas プロパティです。Canvas は Delphi コンポーネントの描画面で，Windows の「デバイスコンテキスト」に相当します。

テキスト印刷でフォントを変更するには次のようにします。

Printer オブジェクトの Canvas の Font プロパティを設定します。

上記のテキストエディタの例の，Print1Click ハンドラの try のすぐ下に次の行を追加します。

Printer.Canvas.Font := Editor.Font	{エディタのフォントをプリンタにコピーする}


Printing graphics
Printing graphics1055018

Section topics	参照

Delphi アプリケーションでグラフィックイメージを印刷するのは簡単です。テキストの場合と同様に，印刷機能の追加に必要な作業は，プリンタを呼び出すフォームの uses 節に Printers ユニットを追加することだけです。Printers ユニットは Printer というプリンタオブジェクトを宣言しています。Printer のキャンバスは印刷ページを表します。

グラフィックイメージを印刷するには次のようにします。

プリンタのキャンバスにイメージをコピーします。

プリンタのキャンバスもほかのキャンバスと同じように使用できます。特に，ビットマップなどのグラフィックオブジェクトの内容もプリンタへ直接コピーできます。次の例では，［Print］メニュー項目に対するクリックに応答して，イメージコントロールの内容をプリンタに印刷します。

procedure TForm1.Print1Click(Sender: TObject);

begin

   with Printer do

   begin

    BeginDoc;	{ 印刷を開始する }

    Canvas.Draw(0, 0, Image.Picture.Graphic);
{ ページの左上にイメージを描画する }

    EndDoc;	{ 印刷を終了する }

   end;

end;


Using the font dialog box
Using the font dialog box1055019

Section topics	参照

設計時に，エディタコンポーネントの Font プロパティを使ってエディタのテキストの初期フォントを設定します。実行時にユーザーが別のフォントを選択できるようにも設定できます。Windows の［フォント］ダイアログボックスを使うと，ユーザーは実行時の環境に合わせて標準の方法でフォントの選択や変更ができます。

次のサンプルテキストエディタアプリケーションの例は，［Character｜Font］の OnClick イベントに次のハンドラを結び付けます。

procedure TEditForm.Font1Click(Sender: TObject);

begin

  FontDialog1.Font := Editor.Font;	{サマリプロパティを設定する}

  if FontDialog1.Execute then	{ダイアログボックスを実行する}

    Editor.Font := FontDialog1.Font;	{サマリプロパティの値を読み出す}

end;

このイベントハンドラは，ユーザーが［Character｜Font］を選択してフォントを変更すると，編集コンポーネント (エディタ) のフォントを変更します。変更はエディタのすべてのテキストに反映されます。


Changing the selected-text font in a rich-text edit component
Changing the selected-text font in a rich-text edit component1055020

Section topics	参照

書式付きテキストコンポーネントをエディタとして使っている場合，テキストの選択箇所だけのフォント属性を変更できます。

書式付きテキストコンポーネントで選択テキストのフォント属性を変更するには次のようにします。

変更後の値をエディタの Font プロパティではなく SelectedText プロパティに割り当てます。

このサンプルアプリケーションでは Font1Click ハンドラにわずかな修正を加えるだけで，エディタのテキストの選択箇所だけを変更できるようになります。

procedure TEditForm.Font1Click(Sender: TObject);

begin

  FontDialog1.Font := Editor.Font;	{サマリプロパティを設定する}

  if FontDialog1.Execute then	{ダイアログボックスを実行する}

    Editor.SelectedText.Assign(FontDialog1.Font);
{サマリプロパティの値を読み出す}

end;	{ここでは := ではなく Assign を使う}


See also1055021

ダイアログコンポーネント

TPrinter


Working with toolbars and cool bars
Working with toolbars and cool bars1076001

Section topics	参照

ツールバーはメニューバーの下に位置するパネルで，通常はフォームの上端に水平に表示されます。ツールバーには主にボタンなどのコントロールが入ります。ツールバーは，アプリケーションの機能をユーザーに使いやすいように視覚的に表示します。Delphi では，簡単にフォームにツールバーを追加できます。クールバーはツールバーの一種で，移動やサイズ変更が可能なバンドを表示します。

フォームには必要なだけツールバーを追加できます。複数のパネルをフォームの上端に配置した場合は，縦方向に追加順に並べられます。

この章では，ツールバーとクールバーの利点について説明し，以下の方法についても説明します。

フォームにツールバーとクールバーを追加する

バーにボタンを格納する

ボタンにグリフを追加する

ツールバーとクールバーの表示および非表示


Different kinds of toolbar control
Different kinds of toolbar control1076002

Section topics	参照

フォームにツールバーを追加するには，いくつかの方法があります。

フォームにパネルを置き (TPanel)，コントロール (スピードボタン) をそれに追加します。

TPanel ではなくツールバーコンポーネント (TToolBar) を使って，それにコントロールを追加します。TToolBar は，ボタンやその他のコントロールを管理し，配置を決め，サイズと場所を自動的に調整します。ツールバーのツールボタン (TToolButton) を使用すると，TToolBar によりボタンが機能によって簡単にグループ化され，その他の表示オプションが提供されます。

クールバー (TCoolBar) コンポーネントを使ってこれにコントロールを追加します。クールバーは，個々に移動やサイズ変更が可能なバンドの上にコントロールを表示します。


Adding a toolbar using a panel component
Adding a toolbar using a panel component1076003

Section topics	参照

パネルコンポーネントを使ってフォームにツールバーを追加する手順は，次のとおりです。

1.	［コンポーネント］パレットの［Standard］ページから，パネルコンポーネントをフォームに追加します 。

2.	パネルの Align プロパティに alTop を設定します。フォームの上端に配置されると，パネルはウィンドウのサイズが変更されても常に一定の高さを持ち，幅はフォームのクライアント領域の幅になります。

3.	このパネルにスピードボタンなどを配置します。


Adding speed buttons to a toolbar panel
Adding speed buttons to a toolbar panel1076004

Section topics	参照

Delphi にはツールバーパネルでの作業用に設計された特殊なボタンとしてスピードボタンがあります。通常，スピードボタンにはキャプションがありません。かわりに，ボタンの機能を示すグリフという小さなグラフィックイメージがあります。

スピードボタンには，以下の 3 つの動作モードがあります。

通常のプッシュボタンとして機能する

クリックに応じてオンとオフに切り替わる

ラジオボタンとして機能する

ツールバーのスピードボタンに関連する作業は，以下の 4 つです。

ツールバーへのスピードボタンの追加

スピードボタンへのグリフの割り当て

スピードボタンの初期設定

スピードボタンのグループ化

Adding a speed button to a panel1076005

ツールバーのパネルにスピードボタンを追加する方法は，次のとおりです。

コンポーネントパレットの［Additional］ページから，パネルにスピードボタンを挿入します。

スピードボタンのオーナーはフォームではなくパネルです。したがって，パネルの移動や非表示化に応じてスピードボタンも移動したり非表示になります。

ツールバーのデフォルトの高さは 41 で，スピードボタンのデフォルトの高さは 25 です。各ボタンの Top プロパティに 8 を設定すれば，各ボタンの縦位置はツールバーの中央になります。デフォルトでは，この位置にスピードボタンが配置されます。

Assigning a speed button's glyph1076006

各スピードボタンには，ボタンの機能をユーザーに示すグリフというグラフィックイメージを付けます。スピードボタンに1つのイメージを指定すると，ボタンを押した状態，押していない状態，選択した状態，使用不可の状態のそれぞれの表示が，そのイメージを基に作成されます。また，各状態に個別のイメージを指定することもできます。

通常は，設計時にスピードボタンにグリフを割り当てます。ただし，実行時に別のグリフを割り当てることもできます。

設計時にスピードボタンにグリフを割り当てる手順は，次のとおりです。

1.	スピードボタンを選択します。

2.	オブジェクトインスペクタで Glyph プロパティを選択します。

3.	Glyph の横の値列をダブルクリックします。
画像エディタが開きます。

4.	画像エディタで［読み込み (L)］ボタンを選択します。
ファイルを開くダイアログボックスが開きます。

5.	ボタンに割り当てるイメージを持つ .BMP ファイルを指定して［OK］を選択します。
ダイアログボックスが閉じられ，画像エディタに指定のビットマップイメージが表示されます。

6.	［OK］を選択して画像エディタを閉じます。

Setting the initial condition of a speed button1076007

ユーザーは，スピードボタンの機能や状態をスピードボタンの外観から判断します。スピードボタンではキャプションを使用しないので，表示するグリフは機能 [image] 状態を示す的確なイメージでなければなりません。

スピードボタンの表示を押された状態にするには次のようにします。

Down プロパティに True を設定します。

スピードボタンの表示を使用不可の状態にするには次のようにします。

Enabled プロパティに False を設定します。

Creating a group of speed buttons1076008

いくつかのスピードボタンをまとめて，相互に排他的なオプションにすることができます。この場合，ボタンをグループとして関連付けして，ユーザーがグループ内のいずれかのボタンをクリックすると，グループ内のほかのボタンが押されていない状態になります。

複数のスピードボタンをグループとして関連付ける方法は次のとおりです。

各スピードボタンの GroupIndex プロパティに同じ番号を割り当てます。
この作業を最も簡単に行うには，グループにまとめるすべてのボタンを選択した状態で，GroupIndex に重複しない値を設定します。


Allowing toggle buttons
Allowing toggle buttons1076009

Section topics	参照

グループ内ですでに押されているボタンを再度クリックして元に戻し，グループ内のボタンが 1 つも押されていない状態にしたい場合もあります。このようなボタンを切り替えボタンと呼びます。グループ内のボタンを切り替えボタンにするには，AllowAllUp を使用します。切り替えボタンは 1 回クリックすると押し下げられ，もう一度クリックすると押し上げられます。

グループ内のスピードボタンを切り替えボタンにするには，次のようにします。

このボタンの AllowAllUp プロパティに True を設定します。

グループ内でいずれかのスピードボタンの AllowAllUp プロパティに True を設定すると，グループ内のすべてのボタンに同じプロパティ値が自動的に設定されます。このグループでは，通常のグループと同じように1つのボタンを押された状態に設定できますが，さらに，すべてのボタンを押されていない状態にすることもできます。


Adding a toolbar using the toolbar component
Adding a toolbar using the toolbar component1076010

Section topics	参照

ツールバーコンポーネント (TToolBar) は，パネルコンポーネントが行わない機能の管理と表示を行います。

ツールバーコンポーネントを使ってフォームにツールバーを追加する手順は，次のとおりです。

1.	コンポーネントパレットの［Win32］ページから，フォームにツールバーコンポーネントを追加します。ツールバーは自動的にフォームの上端に配置されます。

2.	ツールボタンとその他のコントロールをツールバーに追加します。


Adding tool buttons to a toolbar
Adding tool buttons to a toolbar1076011

Section topics	参照

Delphi には，ツールバーコンポーネントで機能するよう設計されたツールボタンと呼ばれる特殊なボタンがあります。スピードボタンと同じように，ツールボタンも以下のことができます。

通常のプッシュボタンとして機能する

クリックに応じてオンとオフに切り替わる

ラジオボタン群として機能する

Adding a tool button to the toolbar1076012

ツールバーにツールボタンを追加するには，次のようにします。

ツールバーを右クリックして，スピードメニューから［ボタン新規作成］を選択します。

ツールボタンのオーナーはツールバーです。したがって，ツールバーの移動や非表示化に応じてツールボタンも移動したり非表示になります。またツールバー上のすべてのツールボタンは，自動的に常に一定の高さと幅を維持します。コンポーネントパレットからツールバーにコントロールをドロップすると，自動的に一定の高さになります。 幅がツールバーに入りきらないときは，折り返して新しい列が作成されます。

Assigning images to tool buttons1076013

各ツールボタンには，実行時に表示するイメージを決める ImageIndex プロパティが含まれます。ツールボタンに 1 つのイメージを指定すると，ボタンが使用不可であるかどうかの表示が，そのイメージを基に作成されます。また，各状態に (使用不可，使用可能，押されている) 個別のイメージを指定することもできます。

設計時にツールボタンにイメージを割り当てる方法は次のとおりです。

1.	ボタンを表示するツールバーを選択します。

2.	オブジェクトインスペクタで，TImageList オブジェクトをツールバーの Images プロパティに割り当てます。イメージリストは同じサイズのアイコンやビットマップの集まりです。

3.	ツールボタンを選択します。

4.	オブジェクトインスペクタで，ツールボタンの ImageIndex プロパティに整数を割り当てます。これはボタンに割り当てるイメージリストのイメージに対応します。

ツールボタンが使用不可のときやマウスポインタが置かれたときに，ツールボタンに個別のイメージを表示するよう指定することもできます。それには，個別イメージリストをツールバーの DisabledImages プロパティと HotImages プロパティにそれぞれ割り当てます。

Setting tool buttons' appearance and initial conditions1076014

ツールボタンの表示を押された状態にするには次のようにします。

Down プロパティに True を設定します。

ツールボタンの表示を使用不可の状態にするには次のようにします。

Enabled プロパティに False を設定します。

ツールバーの左端とその中のコントロールの間に余白を作成するには次のようにします。

ツールバーの Indent プロパティに 0 より大きい値を設定します。

ツールバーを透明にしてツールボタンにポップアップボーダーを指定するには次のようにします。

ツールバーの Flat プロパティに True を設定します。

メモ	TToolBar の Flat プロパティを使用するには，COMCTL32.DLL のバージョン 4.70 以降を必要とします。

特定のツールボタンの後に強制的に新しいコントロールの列を開始するには，次のようにします。

列の最後に表示するツールボタンを選択し，その Wrap プロパティに True を設定します。

ツールバーの自動折り返し機能を解除するには，次のようにします。

ツールバーの Wrapable プロパティに False を設定します。

Creating groups of tool buttons1076015

ツールボタンをグループ化するには，関連付けるボタンを選択して，その Style プロパティに tbsCheck を設定してから，Grouped プロパティに True を設定します。グループ化されたツールボタンを選択すると，同じグループ内のボタンが押し上げられます。

Style プロパティに tbsCheck を設定され，Grouped プロパティに True を設定された隣接する一連のツールボタンは，1 つのグループを形成します。

ツールボタンのグループを解除するには，次のいずれかのボタンを分離します。

Grouped プロパティに False を設定されたツールボタン

Style プロパティに tbsCheck (ツールバーにスペースを空けたり，区切ったり，Style プロパティに tbsSeparator や tbsDivider を設定されたツールボタンを追加したりする) を設定していないツールボタン

ツールボタンのそばの別のコントロール

Allowing toggled tool buttons1076016

グループ内のツールボタンを切り替えボタンにするには，AllowAllUp を使用します。切り替えボタンは 1 度クリックすると押し下げられ，もう一度クリックすると押し上げられます。

グループ内のスピードボタンを切り替えボタンにするには，次のようにします。

このボタンの AllowAllUp プロパティに True を設定します。

スピードボタンと同じように，グループ内でいずれかのツールボタンの AllowAllUp プロパティに True を設定すると，グループ内のすべてのボタンに同じプロパティ値が自動的に設定されます。


Adding a cool bar component
Adding a cool bar component1076017

Section topics	参照

クールバーは rebar とも呼ばれるコンポーネントで，個々に移動可能でサイズ変更可能なバンドの上にウィンドウコントロールを表示します。ユーザーは各バンドの左側でサイズ変更グリップをドラッグして位置を決めることができます。

フォームにクールバーを追加する方法は次のとおりです。

1.	コンポーネントパレットの［Win32］ページから，フォームにクールバーコンポーネントを追加します。クールバーが自動的にフォームの上端に配置されます。

2.	コンポーネントパレットから，クールバーにウィンドウコントロールを追加します。

TWinControl から派生したコンポーネントだけがウィンドウコントロールになります。クールバーには，ラベルやスピードボタンのようなグラフィックコントロールも追加できますが，別々のバンドに表示されるのではありません。

メモ	クールバーコンポーネントを使用するには，COMCTL32.DLL のバージョン 4.70 以降を必要とします。


Configuring the cool bar
Configuring the cool bar1076018

Section topics	参照

クールバーコンポーネントには，次のような役に立つ構成オプションがあります。

クールバーがバンドの大きさに合うように自動的にサイズ変更させるには，AutoSize プロパティに True を設定します。

バンドが一定の高さを維持するようにするには，FixedSize プロパティに True を設定します。

バンドを垂直に配置するようにクールバーを置くには，Vertical に True を設定します (このとき，FixedSize プロパティには別の効果があります)。

クールバーの各バンド (TCoolBand) には独自の Text プロパティがあります。実行時に Text プロパティを表示しないようにするには，クールバーの ShowText プロパティに False を設定します。

バーの周囲の境界を取り除くには，BandBorderStyle に bsNone を設定します。

実行時にユーザーがバンドの順序を変更できないようにするには，FixedOrder に True を設定します (バンドの移動やサイズ変更はできます)。

クールバーの背景イメージを作成するには，TBitmap オブジェクトを Bitmap プロパティに割り当てます。

バンドの左側に表示できるイメージのリストを選択するには，TImageList オブジェクトを Images プロパティに割り当てます。イメージを個々のバンドに割り当てるには，クールバーを選択して，オブジェクトインスペクタで Bands プロパティをダブルクリックします。次にバンドを選択し，その ImageIndex プロパティに値を割り当てます。


Responding to clicks
Responding to clicks1076019

Section topics	参照

ユーザーがツールバーボタンなどのコントロールをクリックすると，アプリケーションには OnClick イベントが発生します。フォームで OnClick イベントを処理するには OnClick イベントハンドラを記述します。


Writing an event handler for a button click
Writing an event handler for a button click1076020

Section topics	参照

スピードボタンとツールボタンのボタンコントロールには，OnClick イベントが組み込まれています。

ユーザーによるボタンのクリックに応答するには，次のようにします。

ボタンのOnClick イベントに対するハンドラを定義します。

デフォルトでは，Delphi は OnClick イベントハンドラの名前をそのコントロールの名前から作成します。たとえば，LineButton というスピードボタンの OnClick イベントハンドラは，次のようになります。

procedure TForm1.LineButtonClick(Sender: TObject);

begin

end;

このイベントハンドラ内に，ユーザーがボタンをクリックしたときの応答を記述します。


Assigning a menu to a tool button
Assigning a menu to a tool button1076021

Section topics	参照

ツールボタン (TToolButton) を持つツールバー (TToolBar) を使用すると，特定のボタンにメニューを簡単に関連付けることができます。

1.	ツールボタンを選択します。

2.	オブジェクトインスペクタで，ツールボタンの DropdownMenu プロパティにポップアップメニュー (TPopupMenu) を割り当てます。

メニューの AutoPopup プロパティに True が設定されていると，ボタンが押されたときメニューが自動的に表示されます。


Adding hidden toolbars
Adding hidden toolbars1076022

Section topics	参照

ツールバーは常に表示されているとは限りません。複数のツールバーが存在する場合，実際に使用するツールバーだけを表示する方が便利です。複数のツールバーを持つフォームを作成したら，一部または全部のツールバーを非表示にできるように考慮します。

非表示のツールバーを作成する手順は，次のとおりです。

1.	フォームにツールバー，クールバー，またはパネルコンポーネントを追加します。

2.	Visible プロパティに False を設定します。

ツールバーは，設計時には常に表示されていて変更したりできますが，実行時にはアプリケーションで明示的に表示しない限り表示されません。


Hiding and showing toolbars
Hiding and showing toolbars1076023

Section topics	参照

アプリケーションで複数のツールバーを使用する場合，すべてを同時に表示するとフォームが混雑します。また，ツールバーをまったく使用しないユーザーもいます。すべてのコンポーネントに共通することですが，ツールバーも必要に応じて表示，非表示を実行時に切り替えられます。

実行時にツールバーを表示または非表示にするには，次のようにします。

Visible プロパティにそれぞれ True または False を設定します。

この設定は，特定のユーザーイベントやアプリケーションの操作モードの変更に対応して行います。

たいていは，各ツールバーにはクローズボタンを追加します。ユーザーがクローズボタンをクリックすると，アプリケーションによりその対応するツールバーが非表示になります。あるいは，ツールバーを切り替える手段を作成することもできます。


See also1076024

標準コンポーネント

Win32 コンポーネント

ツールバー

クールバー


Dragging and dropping
Dragging and dropping1059001

Section topics	参照

項目のドラッグアンドドロップ機能を使用すると，ユーザーはフォームのオブジェクトを簡単に操作できます。コンポーネント全体をドラッグすることも，リストボックスなどのコンポーネントから別のコンポーネントへ項目をドラッグすることもできます。

ドラッグアンドドロップ操作には，以下の 4 つの基本的な要素があります。

1.	ドラッグ操作の開始

2.	ドラッグした項目の受け入れ

3.	項目のドロップ

4.	ドラッグ操作の終了


Starting a drag operation
Starting a drag operation1059002

Section topics	参照

各コントロールには DragMode というプロパティがあります。このプロパティでは，実行時にユーザーがコンポーネントのドラッグを開始したときのコンポーネントの応答方法を指定します。DragMode に dmAutomatic を設定すると，ユーザーがコントロールにポインタを置いてマウスボタンを押すと自動的にドラッグが始まります。一般的には DragMode に dmManual (デフォルト) を設定し，マウスボタンを押したことを示すイベントを処理することでドラッグを開始します。

コントロールのドラッグを (自動的にではなく) 明示的に開始するには次のようにします。

コントロールの BeginDrag メソッドを呼び出します。

BeginDrag は Immediate という論理パラメータを使用します。このパラメータに True を渡すと，DragMode に dmAutomatic を設定した場合と同じように，ドラッグはすぐに開始されます。False を渡すと，ユーザーが実際にマウスを少し移動するまでドラッグは始まりません。呼び出しを BeginDrag (False) と記述すれば，コントロールをクリックしただけではドラッグ操作は開始されません。

BeginDrag を呼び出す前に，マウスボタンが押されたことを示すイベントのパラメータをチェックし，ユーザーが押したボタンを調べてから，条件が合う場合にのみドラッグを開始することもできます。

Example1059003

たとえば，マウスの左ボタンが押された場合のみマウスボタンが押されたことを示すファイルリストボックスのイベントに応答してドラッグを開始するハンドラを次に示します。

procedure TFMForm.FileListBox1MouseDown(Sender: TObject;

  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

begin

 if Button = mbLeft then	{左クリックの場合にのみドラッグする}

   with Sender as TFileListBox do	{Sender を TFileListBox とみなす}

    begin

     if ItemAtPos(Point(X, Y), True) >= 0 then	{ここに項目があるか？}

        BeginDrag(False);	{項目があればドラッグする}

   end;

end;


Accepting dragged items
Accepting dragged items1059004

Section topics	参照

項目をドラッグしてコントロールの上に移動すると，そのコントロールは OnDragOver イベントを受け取ります。このイベントを受け取ったコントロールは，ユーザーがドロップした場合にその項目を受け入れる用意があるかどうかを意志表示しなければなりません。Delphi はドラッグカーソルを変更してコントロールがドラッグされた項目を受け入れることができるかどうかを示します。

ドラッグされた項目をコントロールで受け入れるには次のようにします。

コントロールの OnDragOver イベントに対してイベントハンドラを結び付けます。

このドラッグオーバーイベントには Accept という変数パラメータがあります。項目を受け入れる場合，イベントハンドラはこのパラメータに True を設定します。

Accept に True を設定すると，ユーザーがマウスボタンを放して項目をドロップしたコントロールに対して，ドラッグドロップイベントが送られます。Accept が False であれば，項目はそのコントロールにはドロップされません。このため，各コントロールは処理方法のわからない項目がドロップされないように設定できます。

ドラッグオーバーイベントには，ドラッグのソースやマウスポインタの現在位置などを示す複数のパラメータがあります。イベントハンドラは各パラメータを参照して，ドロップを受け入れるかどうかを判断します。コントロールではほとんどの場合，ドラッグされた項目を受け入れるか拒否するかをドラッグソースの型で決めます。また，特定のインスタンスだけを受け入れることもできます。

Example1059005

次の例では，ファイルリストボックスからドラッグされた項目だけをディレクトリアウトラインで受け入れます。

procedure TFMForm.DirectoryOutline1DragOver(Sender, Source: TObject; X,

  Y: Integer; State: TDragState; var Accept: Boolean);

begin

  if Source is TFileListBox then

    Accept := True;

  else

     Accept := False;

end;


Dropping items
Dropping items1059006

Section topics	参照

ドラッグした項目を受け入れることを意思表示したコントロールでは，ドロップした項目を処理する方法を定義しておく必要があります。ドラッグした項目をコントロールが受け入れ可能なことは，マウスカーソルの変化によってユーザーにもわかります。ユーザーは項目のドロップによって特定の処理が行われることを期待します。

ドロップした項目を処理するには次のようにします。

ドロップした項目を受け入れるコントロールの OnDragDrop イベントに対して，イベントハンドラを結び付けます。

ドラッグオーバーイベントと同じく，ドラッグドロップイベントは，受け入れるコントロール上のマウスポインタの座標と，ドラッグした項目のソースを通知します。ドラッグドロップハンドラでは，このパラメータを利用してドラッグソースから必要な情報を取得し，項目の処理方法を決めることができます。

Example1059007

たとえば，ディレクトリアウトラインはファイルリストボックスからドラッグした項目を受け入れ，ファイルを現在位置からドロップ先のディレクトリに移動できます。

procedure TFMForm.DirectoryOutline1DragDrop(Sender, Source: TObject; X,

  Y: Integer);

begin

  if Source is TFileListBox then

   with DirectoryOutline1 do

      ConfirmChange('Move', FileList.FileName, Items[GetItem(X, Y)].FullPath);

end;

ドラッグアンドドロップを使用すると，ユーザーはファイル名を入力せずに［ファイル(F)｜移動(M)］コマンドと同じ処理を行えます。


Ending a drag operation
Ending a drag operation1059008

Section topics	参照

ドラッグ操作は，ドラッグした項目をドロップするか，またはドラッグした項目を受け入れないコントロールでマウスボタンを放すと終了します。ドラッグ操作が終了すると，ユーザーがドラッグしたコントロールに対して，ドラッグを終了するイベントが送り返されます。

項目のドラッグ元のコントロールでドラッグの終了に応答するには次のようにします。

コントロールの OnEndDrag イベントにイベントハンドラを結び付けます。

OnEndDrag イベントの最も重要なパラメータは Target です。このパラメータはドロップを受け入れたコントロールを示します。Target が nil であれば (何も入っていなければ)，ドラッグした項目を受け入れたコントロールがないことを示します。そうでなければ，Target は項目を受け入れたコントロールを示します。また，OnEndDrag イベントにはドロップを受け入れたコントロール上のドロップ位置の x 座標と y 座標を示すパラメータもあります。

Example1059009

次の例では，ファイルリストボックスはドラッグを終了するイベントに応答してファイルリストを更新します。ファイルリストからファイルをドラッグしたことで，現在のディレクトリ内容に変更が生じた可能性があるからです。

procedure TFMForm.FileList1EndDrag(Sender, Target: TObject; X, Y: Integer);

begin

  if Target <> nil then FileList1.Update;

end;


See also1059010

TListBox

TComboBox

TDBListBox

TDBComboBox

TDBLookupListBox

TDBLookupComboBox


Working with text
Working with text1080001

Section topics	参照

テキストの位置揃え，ワードラップの設定，テキストの切り取り，コピー，貼り付け，削除のような，書式付きテキストエディタやメモコンポーネント内で使用したいオプションを用意する必要がある場合には，フォームのメニュー項目やボタンにイベントハンドラを結びつけます。さらに，クリップボードオブジェクトを使えるようにし，［切り取り］，［コピー］，［貼り付け］などのよく使うコマンドをローカルメニューやポップアップメニューに追加します。最後に，Windows の［フォントの指定］ダイアログボックスを使ってフォント属性を変更します。1080002

この章では，これらすべての機能をアプリケーションに追加する方法について説明します。


Setting text alignment
Setting text alignment1080003

Section topics	参照

書式付きテキストエディタやメモコンポーネントでは，ユーザーはテキストの右揃え，左揃え，中央揃えができます。サンプルのテキストエディタアプリケーション (DEMOS\DOC\TEXTEDIT ディレクトリにある) のメニューでは，有効なオプションにチェックマークが示されます。

位置揃えは WordWrap プロパティが True の場合だけ有効であることに注意してください。ワードラップが使用不可の場合，位置揃えのための右マージンがありません。

エディタにテキストの位置揃えを設定するには次のようにします。

エディタコンポーネントの Alignment プロパティを設定します。

このサンプルでは，子フォームの［Character］メニューにあるテキストの位置揃えの 3 つのコマンドで 1 つのイベントハンドラを共有できます。このイベントハンドラはどの位置揃えオプションが選択されているかを Sender パラメータを使って調べ，Sender の値に従って適切な位置揃えを設定し，対応するメニュー項目のチェックマークを付けるか，またははずします。

次の OnClick イベントハンドラを［Character｜Left］メニュー項目に結び付けます。次に，同じイベントハンドラを［Character｜Right］メニュー項目と［Character｜Center］メニュー項目の両方に結び付けます。

procedure TEditForm.AlignClick(Sender: TObject);

begin

  Left1.Checked := False;	{3 つのすべてのチェックマークをはずす}

  Right1.Checked := False;

  Center1.Checked := False;

  with Sender as TMenuItem do Checked := True;	{クリックされた項目にチェックマークを付ける}

  with Editor do	{Alignment に対応する値を設定する}

    if Left1.Checked then

      Alignment := taLeftJustify

    else if Right1.Checked then

      Alignment := taRightJustify

    else if Center1.Checked then

      Alignment := taCenter;

end;

イベントハンドラの共有についての詳細は，「既存のイベントハンドラにイベントを関連付ける」を参照してください。


Adding scroll bars at runtime
Adding scroll bars at runtime1080004

Section topics	参照

書式付きテキストエディタとメモコンポーネントには，水平スクロールバーと垂直スクロールバーの両方または一方を必要に応じて入れることができます。ワードラップが使用できる場合，コンポーネントが必要とするのは垂直スクロールバーだけです。ユーザーがワードラップを使用不可にした場合，テキストが右マージンで制限されなくなるので，コンポーネントが水平スクロールバーも必要とすることがあります。

実行時にスクロールバーを追加する手順は次のとおりです。

1.	テキストが右マージンを超えることがあるかどうかを調べます。
ほとんどの場合，エディタやメモコンポーネントでワードラップが使用可能になっているかどうかを調べることになります。エディタやメモコンポーネントの幅を実際に超えるテキスト行があるかどうかも調べる必要がある場合があります。

2.	スクロールバーを入れるようにまたは入れないように，エディタやメモコンポーネントの ScrollBars プロパティを設定します。

次の例では，OnClick イベントハンドラを［Character｜Word wrap］メニュー項目に結び付けます。エディタコンポーネントの WordWrap プロパティを切り替える他に， OnClick イベントハンドラは，ScrollBars プロパティに現在のワードラップに対応する値を設定します。

procedure TEditForm.WordWrap1Click(Sender: TObject);

begin

  with Editor do

  begin

    WordWrap := not WordWrap;	{ワードラップの切り替えをする}

    if WordWrap then

      ScrollBars := ssVertical	{ワードラップがあるので垂直スクロールバーだけが必要}

    else

      ScrollBars := ssBoth;	{ワードラップがないので両方のスクロールバーが必要}

    WordWrap1.Checked := WordWrap;
{プロパティに合わせてメニュー項目にチェックマークを付ける}

  end;

end;

書式付きテキストコンポーネントとメモコンポーネントではスクロールバーの処理が少し異なります。書式付きテキストコンポーネントでは，テキストがコンポーネントの範囲内に収まる場合はスクロールバーを非表示にできます。メモコンポーネントでは，スクロールバーは使用可能な場合は必ず表示されます。


Adding the Clipboard object
Adding the Clipboard object1080005

Section topics	参照

ほとんどのテキスト処理アプリケーションでは，異なるアプリケーションの文書も含めて，文書どうしの間で選択したテキストを移動できます。Delphi の「クリップボードオブジェクト」には Windows のクリップボードがカプセル化されており，テキスト (およびグラフィックなどのその他の形式) の切り取り，コピー，貼り付けのためのメソッドが入っています。クリップボードオブジェクトは Clipbrd ユニットで宣言されています。

クリップボードオブジェクトをアプリケーションに追加する手順は次のとおりです。

1.	クリップボードを使うユニットを選択します。

2.	予約語 implementation を探します。

3.	implementation の下の uses 節に Clipbrd を追加します。

implementation 部に uses 節がすでにある場合は，uses 節の最後に Clipbrd を追加します。

uses 節がまだない場合は，次の 1 行を追加します。

  uses Clipbrd;

ユニットと uses 節の使い方についての詳細は「Object Pascal コードの書き方」を参照してください。

たとえば，子ウィンドウを持つアプリケーションでは， ユニットの implementation 部の uses 節は次のようになります。

uses

  MDIFrame, Clipbrd;


About selected text
About selected text1080006

Section topics	参照

クリップボードにテキストを送るには，まずそのテキストを選択します。選択したテキストを強調表示する機能はエディタコンポーネントに組み込まれています。選択したテキストをエディタコンポーネントで表示するために特別にコードを記述する必要はありません。ユーザーがテキストを選択すると，そのテキストは強調表示されます。また，コードを使ってテキストの選択や選択したテキストの操作を可能にする方法もいくつかあります。

エディタコンポーネントには，選択したテキストを処理するためのプロパティやメソッドがいくつかあります。実行時のみのプロパティである SelText には，コンポーネントで選択されているテキストに対応する文字列が入ります。SelectAll メソッドは，エディタコンポーネント内のすべてのテキストを選択します。SelLength メソッドと SelStart メソッドは，選択した文字列の長さの値と開始位置の値をそれぞれ返します。

このサンプルでは，「メニュー項目を使用不可にする」で SelLength を使います。SelStart についての詳細は，「既存のファイルを開く」を参照してください。


Selecting text
Selecting text1080007

Section topics	参照

コードでテキストの選択を可能にする場合，一般的な機能として，ユーザーが書式付きエディタやメモコンポーネントの内容全体を選択できるようにする機能があります。この機能は，コンポーネントの内容が表示領域に収まらない場合に特に役立ちます。その他のほとんどの場合は，ユーザーはキー操作またはマウスのドラッグでテキストを選択します。

書式付きテキストエディタやメモコンポーネントの内容全体を選択するには次のようにします。

エディタの SelectAll メソッドを呼び出します。

次に例を示します。

procedure TEditForm.SelectAll(Sender: TObject);

begin

  Editor.SelectAll;	{エディタのすべてのテキストを選択する}

end;


Cutting, copying, and pasting text
Cutting, copying, and pasting text1080008

Section topics	参照

Clipbrd ユニットを使う Delphi アプリケーションでは，アプリケーション内でもほかのアプリケーションとの間でも，Windows のクリップボードを使ってテキスト，グラフィック，オブジェクトの切り取り，コピー，貼り付けができます。Windows の標準テキスト処理コントロールがカプセル化されているすべてのエディタコンポーネントに，クリップボードとのやり取りのためのメソッドが組み込まれています (グラフィックに対するクリップボードの使い方については「グラフィックファイルの操作」を参照してください)。

クリップボードを使ってテキストの切り取り，コピー，貼り付けを行うには次のようにします。

エディタの CutToClipboard メソッド，CopyToClipboard メソッド，PasteFromClipboard メソッドをそれぞれ呼び出します。

たとえば，［Edit｜Cut］コマンド，［Edit｜Copy］コマンド，［Edit｜Paste］コマンドの OnClick イベントにそれぞれ次のイベントハンドラを結び付けます。

procedure TEditForm.CutToClipboard(Sender: TObject);

begin

  Editor.CutToClipboard;

end;

procedure TEditForm.CopyToClipboard(Sender: TObject);

begin

  Editor.CopyToClipboard;

end;

procedure TEditForm.PasteFromClipboard(Sender: TObject);

begin

  Editor.PasteFromClipboard;

end;


Deleting selected text
Deleting selected text1080009

Section topics	参照

選択したテキストをクリップボードに入れて使うことはよくありますが，エディタで選択したテキストをクリップボードに切り取って入れるのではなく，削除するコードの記述もできます。

選択したテキストをエディタから削除するには次のようにします。

エディタの ClearSelection メソッドを呼び出します。

たとえば［Edit］メニューで，選択したテキストを削除する［Delete］項目のコードは次のようになります。

procedure TEditForm.Delete(Sender: TObject);

begin

  Editor.ClearSelection;

end;


Disabling menu items
Disabling menu items1080010

Section topics	参照

アプリケーションでは，すぐには適用できないメニューコマンドを使用不可にしても，そのコマンドをメニューには残しておく場合がよくあります。たとえば，テキストエディタでは，テキストを選択していないときは［Edit］メニューの［Cut］，［Copy］，［Delete］の各項目は淡色表示になります。項目が使用不可になると，ユーザーはそのようなコマンドはあっても，その時点で適用できないことがわかります。

特定メニューの項目を使用可能または使用不可にするのに適しているのは，ユーザーがメニューの最上位にある項目をクリックした時点です。そうすれば，項目を表示するよりも前に，アプリケーションで適切な項目を利用可能にできます。

メニュー項目を使用不可にするには次のようにします。

そのメニュー項目の Enabled プロパティに False を設定します。

例では，子フォームのメニューバーにある［Edit］項目の OnClick イベントに次のイベントハンドラを結び付けます。［Edit］メニューの［Cut］，［Copy］，［Delete］の各メニュー項目については，エディタでテキストを選択しているかどうかに基づいて Enabled を設定します。［Paste］コマンドについては，クリップボードにテキストがあるかどうかに基づいて使用可能または使用不可にします。

procedure TEditForm.Edit1Click(Sender: TObject);

var

  HasSelection: Boolean;	{一時変数を宣言する}

begin

  Paste1.Enabled := Clipboard.HasFormat(CF_TEXT);
{［Paste］メニュー項目を使用可能または使用不可にする}

  HasSelection := Editor.SelLength > 0;	{テキストが選択されていれば True}

  Cut1.Enabled := HasSelection;
{HasSelection が True であればメニュー項目を使用可能にする}

  Copy1.Enabled := HasSelection;

  Delete1.Enabled := HasSelection;

end;

クリップボードの HasFormat メソッドは，クリップボードの内容が特定形式のオブジェクト，テキスト，イメージかどうかに基づいて論理値を返します。CF_TEXT パラメータとともに HasFormat を呼び出すと，クリップボードの内容がテキストかどうかを調べることができ，適宜に［Paste］項目を使用可能または使用不可にできます。

グラフィックに対するクリップボードの使い方については「グラフィックファイルの操作」を参照してください。


Providing a pop-up menu
Providing a pop-up menu1080011

Section topics	参照

ポップアップまたはローカルメニューは，アプリケーションの操作性を高めるためによく使われる機能です。ポップアップメニューがあると，ユーザーはアプリケーション作業領域内でマウスの右ボタンをクリックするだけで，よく利用するコマンドのリストにアクセスできます。そのためマウスの動きを最小限にできます。

このサンプルでは，たとえば［Cut］，［Copy］，［Paste］の各編集コマンドを繰り返し実行するためのポップアップメニューを追加できます。これらのポップアップメニューの項目では，［Edit］メニューの対応する項目と同じイベントハンドラが使えます。一般に，対応する標準メニュー項目にすでにショートカットキーがあるので，ポップアップメニュー用にアクセラレータキーやショートカットキーを作成する必要はありません。

フォームの PopupMenu プロパティは，ユーザーがフォームの項目を右クリックしたときにどのポップアップメニューが表示されるかを指定します。個々のコントロールにも PopupMenu プロパティがあり，これはフォームの PopupMenu プロパティに優先するため，特定のコントロールに合わせてカスタマイズしたメニューが使えます。

ポップアップメニューをフォームに追加する手順は次のとおりです。

1.	フォームにポップアップメニューコンポーネントを入れます。

2.	メニューデザイナを使ってポップアップメニューの項目を定義します。

3.	ポップアップメニューを表示するフォームまたはコントロールの PopupMenu プロパティにポップアップメニューコンポーネントの名前を設定します。

4.	ポップアップメニューの項目の OnClick イベントにハンドラを結び付けます。


Handling the OnPopup event
Handling the OnPopup event1080012

Section topics	参照

ポップアップメニューを表示する前に，標準メニューの項目を使用可能または使用不可にすることがあるのと同じように，ポップアップメニューの項目を調整しなければならないことがあります。標準メニューでは，「メニュー項目を使用不可にする」で前述したとおり，メニューの最上位にある項目の OnClick イベントを処理します。

しかし，ポップアップメニューでは最上位レベルのメニューバーがないので，ポップアップメニューのコマンドを作成するには，メニューコンポーネント自体のイベントを処理します。ポップアップメニューコンポーネントには，この処理のために OnPopup というイベントがあります。

表示する前にポップアップメニューの項目を調整する手順は次のとおりです。

1.	ポップアップメニューコンポーネントを選択します。

2.	イベントハンドラをポップアップメニューコンポーネントの OnPopup イベントに結び付けます。

3.	イベントハンドラでコードを記述して，メニュー項目を使用可能，使用不可，非表示にしたり，表示したりします。

次の例では，既存の Edit1Clickイベントハンドラをポップアップメニューコンポーネントの OnPopup イベントに結び付けます。次に，各行がポップアップメニューのそれぞれの項目に対応した数行の新しいコードを Edit1Click に追加します。

procedure TEditForm.Edit1Click(Sender: TObject);

var

  HasSelection: Boolean;

begin

  Paste1.Enabled := Clipboard.HasFormat(CF_TEXT);

  Paste2.Enabled := Paste1.Enabled;	{この行を追加する}

  HasSelection := Editor.SelLength <> 0;

  Cut1.Enabled := HasSelection;

  Cut2.Enabled := HasSelection;	{この行を追加する}

  Copy1.Enabled := HasSelection;

  Copy2.Enabled := HasSelection;	{この行を追加する}

  Delete1.Enabled := HasSelection;

end;


See also1080013

TRichEdit

TDBRichEdit

TMemo

TDBMemo

TClipboard

TMenuItem

TPopupMenu

メニューデザイナの使い方


Drawing graphics at runtime
Drawing graphics at runtime1064001

Section topics	参照

Delphi アプリケーションにグラフィックイメージを入れる方法は 3 つあります。設計時に描画済みのグラフィックを挿入する，設計時にグラフィックコントロールで作成する，実行時に動的に描画する，の 3 つです。この章では，実行時にグラフィックを描画する方法を解説します。描画先は，ウィンドウ，カスタムコントロール，オーナー描画コントロールのいずれかとします。設計時にイメージコントロールでグラフィックを作成する方法については「オーナー描画コントロールの作成」で解説します。

Delphi アプリケーションでグラフィックを描画する場合は，オブジェクトには直接描画せず，オブジェクトのキャンバスに描画します。キャンバスはオブジェクトのプロパティですが，キャンバス自体も独自のプロパティを持つオブジェクトです。キャンバスオブジェクトには 4 つの重要なプロパティがあります。線を描画するペン，塗りつぶしのためのブラシ，テキスト表示のためのフォント，イメージを表すピクセル配列，の 4 つです。

Font プロパティについての詳細は，「Windows コモンダイアログボックスの使い方」を参照してください。この章ではペン，ブラシ，ピクセル配列の使い方を説明します。

キャンバスを使用できるのは実行時だけです。したがって，キャンバスで行う作業のすべてはコードで記述します。キャンバスと Windows のグラフィックデバイスインターフェース (GDI) とは，ほぼ対応しています。ただし，キャンバスを使用する方が GDI を直接呼び出すよりも簡単です。

実行時にグラフィックを効果的に使用するには、以下の点を理解する必要があります。

描画とペイントの相違

ピクセル配列の使い方

直線と多角線の描画

図形の描画

その他の描画機能


Drawing versus painting
Drawing versus painting1064002

Section topics	参照

グラフィック処理では，描画とペイントという用語がよく使われます。描画とペイントは異なる概念であり，この違いを理解することは大切です。

描画とは，線や図形などの個々のグラフィック要素をコードで作成することです。キャンバスの描画メソッドを呼び出して，指定のグラフィックを指定の場所に描画することをコードでオブジェクトに指示します。

ペイントとは，オブジェクト全体の外観を作成することです。Windows は必要に応じて画面のオブジェクトの外観を更新するために OnPaint イベントを生成します。OnPaint イベントは，ほかのウィンドウの後ろに隠されていたウィンドウを手前に表示する場合などに生成されます。

重要な点は，ペイントは常に描画を伴うということです。つまり，オブジェクトは OnPaint イベントへの応答の中でグラフィックを描画します。たとえば編集ボックスは，四角形を描画し，さらに四角形内にテキストを描画することで編集ボックス全体をペイントします。一方，図形コントロールは，単一のグラフィックを描画することで図形コントロール全体をペイントします。

この章の最初の例では各種のグラフィックを描画する方法を示しますが，すべてを OnPaint イベントへの応答の中で描画します。後半の例では，ほかのイベントに応答して描画する方法を示します。


Using the pixel array
Using the pixel array1064003

Section topics	参照

すべてのキャンバスには Pixels というインデックス付きのプロパティがあります。Pixels は，キャンバスでイメージを構成する色を持った個々の点を表します。個々のピクセルに対して行える処理は，色の読み出しと設定だけです。それ以外は Pixels に直接アクセスする必要はめったにありません。重要なのは，Pixels が全体としてキャンバスの描画面を構成しており，ペンやブラシを利用すればピクセルをグループにまとめて簡単に操作できるということです。

この節では以下の内容について説明します。

ピクセルの操作

ペンの使い方

ブラシの使い方


Manipulating pixels
Manipulating pixels1064004

Section topics	参照

キャンバスのピクセル群は，色を各要素の値とする 2 次元の配列と考えることもできます。個々のピクセルに対しては，色の読み出しと設定が可能です。

Reading a pixel's color1064005

特定のピクセルの色を読み出すには次のようにします。

読み出すピクセルの x 座標と y 座標をインデックスとして，キャンバスの Pixels プロパティにアクセスします。キャンバスの左上隅が座標系の原点です。

たとえば，チェックボックスのクリックに応答してチェックボックスのテキストの色をフォームの座標 (10, 10) のピクセルの色に変更するイベントハンドラは次のとおりです。

procedure TForm1.CheckBox1Click(Sender: TObject);

begin

  CheckBox1.Font.Color := Canvas.Pixels[10, 10];

end;

Setting a pixel's color1064006

ピクセルの色を設定するには次のようにします。

ピクセルの x 座標と y 座標をインデックスとして Pixels プロパティに色の値を代入します。

たとえば，ボタンのクリックに応じてフォームのランダムなピクセルを赤色に変更するイベントハンドラは，次のとおりです。なお，Random 関数についての詳細はオンラインヘルプを参照してください。

procedure TForm1.Button1Click(Sender: TObject);

begin

  Canvas.Pixels[Random(ClientWidth), Random(ClientHeight)] := clRed;

end;


Using pens
Using pens1064007

Section topics	参照

キャンバスの Pen プロパティでは，線の表示方法を指定します。図形の輪郭線も線の一種です。実際には，直線を描画することは 2 点間を結ぶピクセル群を変更することと同じです。

ペン自体には，変更可能な 4 つのプロパティ，Color，Width，Style，Mode があります。

これらのプロパティの値は，線上のピクセルをどのように変更するかを指定します。デフォルトのペンの色 (Color) は黒，幅 (Width) は 1 ピクセル，スタイル (Style) は実線，モード (Mode) はキャンバスにあるものすべてを上書きするコピーモードです。

ペンの色を設定する方法は，ほかのオブジェクトで Color プロパティを実行時に設定する方法と同じです。Width は整数値 (単位はピクセル) です。Style には実線，破線，点線などがあります。Mode にはピクセル配列の既存の色とペンの色をさまざまに組み合わせる方法を指定します。

詳細については「ペンとブラシのカスタマイズ」を参照してください。


Moving the pen
Moving the pen1064008

Section topics	参照

現在の描画位置，つまりペンで次に線を描画する始点を，ペン位置といいます。キャンバスではペン位置を PenPos というプロパティに格納します。ペン位置が影響するのは線の描画だけであり，図形とテキストの描画では任意の座標を指定できます。

ペン位置を設定するには次のようにします。

キャンバスの MoveTo メソッドを呼び出します。

たとえば，ペン位置をキャンバスの左上隅に移動するコードは，次のとおりです。

Canvas.MoveTo(0, 0);

メモ	LineTo メソッドで線を描画すると，ペン位置は線の終端に移動します。


Using brushes
Using brushes1064009

Section topics	参照

キャンバスの Brush プロパティでは，領域を塗りつぶす方法を指定します。図形の内部を領域とすることもできます。ブラシで領域を塗りつぶすことは，隣接ピクセル群を特定の方法で変更することです。

ブラシには，操作可能な 3 つのプロパティ，Color，Style，Bitmap があります。

各プロパティの値は，キャンバスで図形などの領域をどのように塗りつぶすかを指定します。デフォルトのブラシの色 (Color) は白，スタイル (Style) は実線，ビットマップ (Bitmap) はパターンなしです。

ブラシの色を設定する方法は，ほかのオブジェクトで Color プロパティを実行時に設定する方法と同じです。Style には，キャンバスの既存の色とブラシの色をさまざまに組み合わせる方法を指定します。Bitmap には，図形などの領域を塗りつぶすときにパターンとして使用するビットマップイメージを指定します。

詳細は「ペンとブラシのカスタマイズ」を参照してください。


Drawing lines and polylines
Drawing lines and polylines1064010

Section topics	参照

キャンバスでは直線と多角線の 2 種類の線を描画できます。直線は単に 2 点間を結ぶ線です。多角線は複数の直線をつなげたものです。キャンバスではすべての線をペンで描画します。


Drawing straight lines
Drawing straight lines1064011

Section topics	参照

キャンバスに直線を描画するには次のようにします。

キャンバスの LineTo メソッドを使用します。

LineTo では現在のペン位置から指定した点まで線を描画し，線の終端を現在のペン位置にします。キャンバスでは直線をペンで描画します。

たとえば，フォームのペイントでフォーム全体に交差する斜線を描画するメソッドは，次のとおりです。

procedure TForm1.FormPaint(Sender: TObject);

begin

  with Canvas do

  begin

    MoveTo(0, 0);

    LineTo(ClientWidth, ClientHeight);

    MoveTo(0, ClientHeight);

    LineTo(ClientWidth, 0);

  end;

end;

Windows はフォームの再描画が必要なときに OnPaint イベントを生成します。たとえば，ほかのウィンドウに隠されたウィンドウを再び表示する場合などです。フォームの OnPaint イベントにはハンドラ FormPaint がデフォルトで生成されています。フォームの背景をペイントしたりイメージを再表示する場合は，OnPaint イベントを処理します。

この章の以降の例も OnPaint イベントハンドラで描画します。「アプリケーションでの描画方法」では，対話式でキャンバスに描画する方法を示します。


Drawing polylines
Drawing polylines1064012

Section topics	参照

キャンバスでは孤立した線だけでなく，多角線も描画できます。多角線とは，複数の線分をつなげたものです。

キャンバスで多角線を描画するには次のようにします。

キャンバスの PolyLine メソッドを呼び出します。

PolyLine メソッドにはパラメータとして点の配列を渡します。多角線は，最初の点に対して MoveTo を実行し，後続の各点に対して LineTo を実行するものと考えることもできます。

たとえば，フォームにひし形を描画するメソッドは次のとおりです。

procedure TForm1.FormPaint(Sender: TObject);

begin

  with Canvas do

    PolyLine([Point(0, 0), Point(50, 0), Point(75, 50), Point(25, 50), Point(0, 0)]);

end;

この例では，Delphi のオープン配列パラメータの作成機能を利用しています。PolyLine 関数にはどのような点の配列でも渡せますが，大カッコ ([ ]) に配列の要素を入れ，大カッコごとパラメータとして渡すと簡単です。詳細はオンラインヘルプを参照してください。


Drawing shapes
Drawing shapes1064013

Section topics	参照

キャンバスには 4 種類の図形を描画するメソッドがあります。キャンバスでは図形の輪郭線をペンで描画し，図形内部をブラシで塗りつぶします。

図形の描画には，以下の 3 種類があります。

四角形と楕円の描画

角の丸い四角形の描画

多角形の描画

四角形，楕円，角の丸い四角形の描画方法は類似しています。多角形だけは少し異なります。


Drawing rectangles and ellipses
Drawing rectangles and ellipses1064014

Section topics	参照

キャンバスに四角形または楕円を描画するには次のようにします。

キャンバスの Rectangle メソッドまたは Ellipse メソッドを呼び出して，境界となる四角形の座標を渡します。

Rectangle メソッドは境界四角形をそのまま描画し，Ellipse メソッドは境界四角形の 4 辺に接触する楕円を描画します。

たとえば，フォームの左上半分に四角形を描画し，この四角形内に楕円を描画するメソッドは次のとおりです。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.Rectangle(0, 0, ClientWidth div 2, ClientHeight div 2);

  Canvas.Ellipse(0, 0, ClientWidth div 2, ClientHeight div 2);

end;


Drawing rounded rectangles
Drawing rounded rectangles1064015

Section topics	参照

キャンバスに角の丸い四角形を描画するには次のようにします。

キャンバスの RoundRect メソッドを呼び出します。

Rectangle や Ellipse と同じように，RoundRectに渡す最初の 4 つのパラメータは境界四角形を示します。RoundRect では，丸い角の描画方法を指示する 2 つのパラメータも指定します。

たとえば，フォームの左上半分に角の丸い四角形を描画し，角は直径 10 ピクセルの円弧とするメソッドは次のとおりです。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.RoundRect(0, 0, ClientWidth div 2, ClientHeight div 2, 10, 10);

end;


Drawing polygons
Drawing polygons1064016

Section topics	参照

キャンバスに複数の辺を持つ多角形を描画するには次のようにします。

キャンバスの Polygon メソッドを呼び出します。

Polygon は点の配列だけをパラメータとして受け取り，各点をペンでつなげます。さらに最後の点を最初の点に接続して，閉じた多角形を作ります。Polygon は多角形の各線を描画した後で，内部の領域をブラシで塗りつぶします。

たとえば，フォームの左下半分に直角三角形を描画するメソッドは次のとおりです。

procedure TForm1.FormPaint(Sender: TObject);

begin

  Canvas.Polygon([Point(0, 0), Point(0, ClientHeight),

    Point(ClientWidth, ClientHeight)]);

end;


Drawing special parts
Drawing special parts1064017

Section topics	参照

この章で説明した線や図形とは別に，キャンバスでは，扇形，円弧，弦などの特殊なグラフィックを描画できます。また，領域や四角形を塗りつぶしたり，ほかのキャンバスのイメージをコピーすることもできます。キャンバスで描画できるグラフィックについての詳細は，オンラインヘルプの「TCanvas コンポーネント」を参照してください。


Techniques for drawing in an application
Techniques for drawing in an application1064018

Section topics	参照

この章の後半では Delphi に付属する単純なグラフィックアプリケーションを作成します。このサンプルアプリケーションでは，クリックとドラッグに応じて直線や図形を描画します。マウスボタンが押されたら描画を開始し，マウスボタンが放されたら描画を終了します。

サンプルグラフィックアプリケーションを表示するには，DEMOS\DOC\GRAPHEX ディレクトリにあるプロジェクトファイル GRAPHEX.DPR を開きます。

図にアプリケーションで図を描いたときの状態を示します。1064019

初めの例では，メインフォームに描画する方法を示し，後の例ではビットマップに描画する方法を示します。


Responding to the mouse
Responding to the mouse1064020

Section topics	参照

このアプリケーションでは，4 種類のマウス操作に応答します。そのうちの3種類は，マウスボタンを押す，マウスを移動する，マウスボタンを放す，というマウス固有の操作です。4 つ目の種類はクリックです。クリックは，マウスボタンを一箇所で押して放す操作です。クリックは，キーストロークでも同じことを行える場合があるという点で，ほかの 3 つの操作と少し異なります。たとえば，モード付きダイアログボックスでは，ボタンをクリックするかわりに〔Enter〕キーを押すこともできます。

マウスイベントについて，以下の 4 つの点を順に説明します。

マウスイベントのハンドラ

マウスボタンが押されたことを示すイベントへの応答

マウスボタンが放されたことを示すイベントへの応答

マウスの移動への応答

What's in a mouse event?1064021

Delphi には，OnMouseDown，OnMouseMove，OnMouseUp の 3 つのマウスイベントが定義されています。

Delphi アプリケーションでは，マウスイベントを検出すると，このイベントに対して定義されたイベントハンドラが呼び出され，5 つのパラメータを受け取ります。各パラメータの情報は，イベントに対する応答をカスタマイズするのに使用します。この 5 つのパラメータを次の表に示します。

パラメータ	説明
Sender	マウスイベントを検出したオブジェクト
Button	関与したマウスボタンを示し，mbLeft，mbMiddle，mbRight のいずれかの値になる
Shift	マウスイベント発生時の〔Alt〕，〔Ctrl〕，〔Shift〕の各キーの状態を示す
X, Y	イベントが発生した座標
ほとんどの場合，マウスイベントハンドラで最も重要な情報は座標です。また，Button をチェックしてイベントを起こしたマウスボタンを特定することもあります。

メモ	Delphi では，押されたマウスボタンの特定は Microsoft Windows と同じ判定条件で行われます。したがって，デフォルトの「一次」ボタンと「二次」ボタンの設定を切り替えて，右マウスボタンを一次ボタンとした場合も，一次ボタン (この場合右) をクリックしたときに Button パラメータの値に記録されるのは mbLeft です。

Responding to a mouse-down action1064022

ユーザーがマウスボタンを押すと，マウスポインタの位置にあるオブジェクトで OnMouseDown イベントが発生します。イベントに応答できるのは，イベントの発生した場所にあるオブジェクトです。

マウスボタンが押されたことを示すイベントに応答するには次のようにします。

OnMouseDown イベントにイベントハンドラを結び付けます。

Delphi は，フォームのマウスボタンが押されたことを示すイベントに対して空のハンドラを生成します。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

end;

マウスボタンを押した位置に適当なテキストを表示するように記述してみます。特定の位置にテキストを表示するには，メソッドに送られる X パラメータと Y パラメータで座標を指定し，キャンバスの TextOut メソッドを呼び出します。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Canvas.TextOut(X, Y, 'Here!');	{ write text at (X, Y) }

end;

ここでアプリケーションを実行し，フォーム上にマウスポインタを置いてマウスボタンを押すと，ポインタの位置に文字列が表示されます (図を参照)。

Drawing text at the point clicked1064023

ボタンを押しただけでは，アプリケーションは描画の開始位置しか特定できません。直線を描画するには，始点と終点を指定しなければなりません。

次のサンプルでは，現在のペン位置をユーザーがボタンを押した座標に設定するようにします。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Canvas.MoveTo(X, Y);	{ set pen position }

end;

マウスボタンを押すと，ペン位置が設定されて直線の始点になります。さらに，ユーザーがマウスボタンを放した座標を直線の終点とすることにします。このためには，マウスボタンが放されたことを示すイベントに応答しなければなりません。

Responding to a mouse-up action1064024

ユーザーがマウスボタンを放すと，OnMouseUp イベントが発生します。このイベントは，ユーザーがボタンを押したときのマウスポインタ位置にあったオブジェクトにおいて発生します。このオブジェクトと，ボタンを放したときのポインタ位置にあるオブジェクトとは，必ずしも一致するとは限りません。このような仕様になっているので，たとえば，フォームの境界外まで延長した線でも描画できます。

マウスボタンが放されたことを示すイベントに応答するには次のようにします。

OnMouseUp イベントのハンドラを定義します。

マウスボタンを放した位置まで直線を描画する単純な OnMouseUp イベントハンドラを，次に示します。

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Canvas.LineTo(X, Y);	{ draw line from PenPos to (X, Y) }

end;

これでユーザーは，マウスをクリック，ドラッグしてボタンを放せば直線を描画できます (図を参照)。

Graphics application with lines drawn1064025

この場合，マウスボタンを放すまで線を見ることはできません。次の節では，マウスの移動中に一時的な線を描画して，ユーザーに操作の状況をフィードバックします。

Responding to a mouse move1064026

ユーザーがマウスを移動すると，移動中は OnMouseMove イベントが発生します。このイベントは，ユーザーがボタンを押したときのマウスポインタ位置にあったオブジェクトにおいて発生します。

マウスの移動に応答するには次のようにします。

フォームの OnMouseMove イベントに対してハンドラを定義します。

このサンプルでは，マウスボタンを押したままマウスを移動したときのイベントを利用して一時的な直線を描画し，ユーザーに動作がわかるようにします。フォームで OnMouseMove イベントの発生した位置まで線を描画する単純な OnMouseMove イベントハンドラを次に示します。

procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Canvas.LineTo(X, Y);	{ draw line to current position }

end;

ここでアプリケーションを実行すると，マウスボタンを押さなくても，マウスの動くとおりに描画が行われてしまいます (図を参照)。

Graphics application following the mouse1064027

マウスの移動イベントはマウスボタンを押さなくても発生します。

マウスボタンが押されているかどうかを追跡するには，フォームオブジェクトにオブジェクトフィールドを追加します。


Adding a field to a form object
Adding a field to a form object1064028

Section topics	参照

フォームにコンポーネントを追加すると，追加したコンポーネントに対応するフィールドがフォームオブジェクトに追加されます。したがって，このフィールド名によって追加したコンポーネントを参照できます。なお，コンポーネント型フィールドについての詳細は，「Delphi オブジェクトを使ったプログラミング」を参照してください。また，フォームユニットの先頭の型宣言を編集すれば，独自のフィールドをフォームに追加することもできます。

オブジェクトにフィールドを追加するには次のようにします。

オブジェクトの型宣言を編集し，型宣言の最後の public 指令に続けて，追加するフィールドの識別子と型を指定します。

public 指令の前にある宣言は Delphi が作成したものです。Delphi はこの部分に，コントロールを示すフィールドとイベントに応答するメソッドを宣言します。

論理型のフィールド Drawing をフォームに追加するには，フォームオブジェクトの宣言を編集して次のようにします。ここには，TPoint 型の 2 つのフィールド，Origin と MovePt も追加しています。

type

  TForm1 = class(TForm)

    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

    procedure FormMouseUp(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

    procedure FormMouseMove(Sender: TObject; Button: TMouseButton;

      Shift: TShiftState; X, Y: Integer);

  public

    Drawing: Boolean;	{ボタンが押されたかどうかを追跡するフィールド}

    Origin, MovePt: TPoint;

  end;

マウスボタンが押されているかどうかを追跡する Drawing フィールドができたら，次はユーザーがボタンを押したときに Drawing に True を設定し，ボタンを放したときに Drawing に False を設定します。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

   Shift: TShiftState; X, Y: Integer);

begin

  Drawing := True;	{Drawing フラグを設定する}

  Canvas.MoveTo(X, Y);

end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

   Shift: TShiftState; X, Y: Integer);

begin

  Canvas.LineTo(X, Y);

  Drawing := False;	{Drawing フラグをクリアする}

end;

OnMouseMove イベントハンドラを変更し，Drawing が True の場合にのみ描画させます。

procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then	{Drawingフラグが設定されている場合にのみ描画する}

    Canvas.LineTo(X, Y);

end;

これで，マウスボタンを押して，移動し，マウスボタンを放すまで線が描画されます。しかし，まだ不十分です。マウスの移動を追跡して描画される線は，図のようにいたずら書きのようで直線ではありません。1064029

問題は，マウスを移動するたびにマウスの移動イベントハンドラが LineTo を呼び出して，ペン位置を移動させてしまうことです。マウスボタンを放す頃には，直線を描こうとしても始点の位置がわからなくなっています。

次の節では，追加した Origin フィールドと MovePt フィールドを使用して，始点と途中の各点を記録します。


Refining line drawing
Refining line drawing1064030

Section topics	参照

すでに追加したフィールドでさまざまな点を記録できるので，目的の直線を描けるようになります。

Tracking the origin point1064031

直線の描画では始点を記録することが最も重要です。線の終点は簡単にわかります。マウスボタンを放した位置，つまり OnMouseUp イベントの発生した位置だからです。しかし，OnMouseUp イベントハンドラは線の始点も取得しなければなりません。この役割を果たすのが Orign フィールドです。

OnMouseDown イベントの発生位置を Origin に記録すれば，OnMouseUp イベントハンドラはこの Origin を参照して線の始点を特定できます。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Drawing := True;

  Canvas.MoveTo(X, Y);

  Origin := Point(X, Y);	{線の始点を記録する}

end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Canvas.MoveTo(Origin.X, Origin.Y);	{ペンを始点へ移動する}

  Canvas.LineTo(X, Y);

  Drawing := False;

end;

これで，意図した直線を描けるようになりました。しかし，マウス移動中に表示する一時的な線については，まだ問題が残ったままです。

Tracking movement1064032

これまでに記述した OnMouseMove イベントハンドラの問題は，マウスの移動中にマウスの通った跡に線を描いてしまうことです。直前のペン位置からではなく始点から現在位置までの線が描かれるようにしなければなりません。

しかし，アプリケーションは始点を記録するように変更されたので，この問題は簡単に修正できます。ペン位置を始点に移動してから現在位置へ向けて描画すればよいのです。

procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then

  begin

    Canvas.MoveTo(Origin.X, Origin.Y);	{ペンを始点に移動する}

    Canvas.LineTo(X, Y);

  end;

end;

これで，線を始点から現在のマウス位置へ描画するようになりました。しかし，これではマウスの移動に伴って始点からマウス位置へのいくつもの直線ができるので，最終的な線を見分けられません。

この問題を解決するため，次の線を描くときに前の線を消すようにします。それには，前の線の位置も記録しなければなりません。この役割を果たすのが前に追加した MovePt フィールドです。

MovePt には一時的な線の終点を記録します。MovePt と Origin を使用すれば，前の線を消去してから新しい線を描くことができます。

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  Drawing := True;

  Canvas.MoveTo(X, Y);

  Origin := Point(X, Y);

  MovePt := Point(X, Y);	{この移動の開始位置を記録する}

end;

procedure TForm1.FormMouseMove(Sender: TObject;Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then

  begin

    Canvas.Pen.Mode := pmNotXor;	{XOR モードで描画，消去する}

    Canvas.MoveTo(Origin.X, Origin.Y);	{ペンを始点に戻す}

    Canvas.LineTo(MovePt.X, MovePt.Y);	{前の線を消去する}

    Canvas.MoveTo(Origin.X, Origin.Y);	{ペンを始点に戻す}

    Canvas.LineTo(X, Y);	{新しい線を描画する}

  end;

  MovePt := Point(X, Y);	{今回の線を消去するときのために終点を記録する}

  Canvas.Pen.Mode := pmCopy;

end;

これで，線を描画するときに見事な「ラバーバンド」効果を得られます。ペンのモードを pmNotXor にすると，線の描画は背景ピクセルと結び付ける形で行われます。そのため，線を消去すると，ピクセルが元の色に戻ります。一時的な線を描画した後ペンのモードをデフォルトの pmCopy に戻すと，マウスボタンを放したときにペンで最終的な線を描けるようになります。

線だけでなく，これから四角形や楕円などの図形を描くとき，ここまでの知識が役に立ちます。


Drawing with different tools
Drawing with different tools1064033

Section topics	参照

この節では，スピードボタンのクリックに応答してフォームの描画ツールを設定する方法を説明します。

この節では以下の内容について説明します。

列挙型の宣言

スピードボタンによるツールの変更

描画ツールの使い方


Declaring an enumerated type
Declaring an enumerated type1064034

Section topics	参照

このサンプルグラフィックプログラムでは，ユーザーが使用している描画ツールの種類を保持している必要があります。ツールの種類ごとに数値を割り当てることが考えられますが，ツールと数値の対応を管理するのが大変です。各数値に略名を付けると少しはわかりやすくなりますが，コードはどの数値が適切な範囲にあり正しい型になっているか区別できません。しかし，Object Pascal には両方の欠点に対処できる優れた方法があります。それは列挙型を宣言することです。

列挙型は定数に連続した値を割り当てるための簡単な方法です。同時に列挙型は型宣言でもあり，Object Pascal の型チェックの対象になるので，確実に適切な値だけを割り当てられます。

列挙型を宣言するには次のようにします。

type 予約語，型の識別子，等号を順番に記述し，さらに，その型の値を割り当てるための識別子を丸カッコ内にカンマ (,) で区切って記述します。

グラフィックアプリケーションの各描画ツールに対して列挙型を宣言するコードの例を，次に示します。

type

  TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);

慣例として型識別子は文字 T で始めます。また，1 つの列挙型に属する各定数の名前は，先頭に同一の 2 文字を付加します。たとえば，描画ツール (drawing tool) では dt を付けることにします。

TDrawingTool 型の宣言は，次のように各定数を宣言することと実質的には同じです。

const

  dtLine = 0;

  dtRectangle = 1;

  dtEllipse = 2;

  dtRoundRect = 3;

主な違いは，列挙型の宣言では定数に値だけでなく型も指定するので，Object Pascal の型チェックを利用してエラーを未然に防げる点です。TDrawingTool 型の変数には定数 dtLine，dtRectangle，dtEllipse，dtRoundRect の中の 1 つを代入できます。かわりに数値を代入しようとすると，コンパイル時エラーになります。代入する数値が 0～3 の範囲に属する場合でもエラーになります。

次のように，描画ツールを追跡するためのフィールドをフォームに追加します。

type

  TDrawingTool = (dtLine, dtRectangle, dtEllipse, dtRoundRect);

  TForm1 = class(TForm)

    ...	{メソッド宣言}

  public

    Drawing: Boolean;

    Origin, MovePt: TPoint;

    DrawingTool: TDrawingTool;	{現在のツールを保持するフィールド}

  end;

フォームを含めて，すべてのオブジェクトのフィールドは 0 に初期化されるので，アプリケーションを起動したときの描画ツールは dtLine になります。


Changing the tool with speed buttons
Changing the tool with speed buttons1064035

Section topics	参照

アプリケーションでは各描画ツールに OnClick イベントハンドラが必要です。線，四角形，楕円，角の丸い四角形の 4 つの描画ツールに対応する 4 つのツールボタンがあるとします。ツールバーの 4 つの描画ツールボタンの OnClick イベントに対して，次のイベントハンドラを記述し，各 DrawingTool に適切な値を設定します。

procedure TForm1.LineButtonClick(Sender: TObject);	{ LineButton }

begin

  DrawingTool := dtLine;

end;

procedure TForm1.RectangleButtonClick(Sender: TObject);	{ RectangleButton }

begin

  DrawingTool := dtRectangle;

end;

procedure TForm1.EllipseButtonClick(Sender: TObject);	{ EllipseButton }

begin

  DrawingTool := dtEllipse;

end;

procedure TForm1.RoundedRectButtonClick(Sender: TObject);	{ RoundRectButton }

begin

  DrawingTool := dtRoundRect;

end;

使用するツールをフォームに指示できるようになったので，残る作業は各種の図形を描画する方法をフォームに指示するだけです。どのツールを使用する場合でも，OnMouseMove と OnMouseUp の両ハンドラの描画コードによってのみ描画を行います。


Using drawing tools
Using drawing tools1064036

Section topics	参照

さまざまな描画ツールを使用するには，ユーザーが指定したツールに対応した描画方法を選択するように，指定する必要があります。それには，各ツールのイベントハンドラにコードを追加します。

この節で解説する内容は以下のとおりです。

ツールの効率的な選択

適切な図形の描画

フォームへのメソッドの追加


Making efficient choices
Making efficient choices1064037

Section topics	参照

描画ツールの選択肢が少なければ，描画メソッドを少し修正し，描画ツールごとに次のようなコードを追加すれば目的を達成できます。

procedure TForm1.FormMouseUp(Sender: TObject);

begin

  if DrawingTool = dtLine then { 直線を描く }

  else if DrawingTool = dtRectangle then { 四角形を描く }

  { ... 以下省略 ... }

end;

ここで，{ 直線を描く } などのコメント部分には，先に記述したように，直線などを描画するコードのブロックを記述します。

しかし，描画ツールの数が多い場合は，この方法では手間がかかり効率もよくありません。Object Pascal では，case 文を使用してツールを切り替えるという便利な方法が使えます。特に case 文が優れている点は，新しいツールの選択肢を後で簡単に追加できることです。

上記のメソッドを if..then..else 文でなく case 文を使用して書き直すと次のようになります。

procedure TForm1.FormMouseUp(Sender: TObject);

begin

  case DrawingTool of

    dtLine: { 直線を描く }

    dtRectangle: { 四角形を描く }

    { ... 以下省略 ... }

  end;

end;

Drawing the appropriate shapes1064038

図形の描画は，直線の描画と同じように簡単です。図形ごとに 1 つの文を記述するだけです。すべての必要な座標はすでに取得済みです。

OnMouseUp イベントハンドラを修正して，定義した 4 つすべてのツールで図形を描画できるようにします。

procedure TForm1.FormMouseUp(Sender: TObject);

begin

  case DrawingTool of

    dtLine:

      begin

        Canvas.MoveTo(Origin.X, Origin.Y);

        Canvas.LineTo(X, Y)

      end;

    dtRectangle: Canvas.Rectangle(Origin.X, Origin.Y, X, Y);

    dtEllipse: Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

    dtRoundRect: Canvas.RoundRect(Origin.X, Origin.Y, X, Y,

                   (Origin.X - X) div 2, (Origin.Y - Y) div 2);

  end;

  Drawing := False;

end;

もちろん，図形を描画するには OnMouseMove ハンドラも更新します。

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then

  begin

    Canvas.Pen.Mode := pmNotXor;

    case DrawingTool of

      dtLine: begin

          Canvas.MoveTo(Origin.X, Origin.Y);

          Canvas.LineTo(MovePt.X, MovePt.Y);

          Canvas.MoveTo(Origin.X, Origin.Y);

          Canvas.LineTo(X, Y);

        end;

      dtRectangle: begin

          Canvas.Rectangle(Origin.X, Origin.Y, MovePt.X, MovePt.Y);

          Canvas.Rectangle(Origin.X, Origin.Y, X, Y);

        end;

      dtEllipse: begin

          Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

          Canvas.Ellipse(Origin.X, Origin.Y, X, Y);

        end;

      dtRoundRect: begin

          Canvas.RoundRect(Origin.X, Origin.Y, X, Y,

              (Origin.X - X) div 2, (Origin.Y - Y) div 2);

          Canvas.RoundRect(Origin.X, Origin.Y, X, Y,

              (Origin.X - X) div 2, (Origin.Y - Y) div 2);

        end;

    end;

    MovePt := Point(X, Y);

  end;

  Canvas.Pen.Mode := pmCopy;

end;

これらのメソッドで同じコードが繰り返されていることに気付いたでしょう。実際，各図形を描画するコードは 3 回も出てきます。このような場合は，コードの繰り返し部分を別のルーチンにまとめます。次の節では，図形を描画するすべてのコードを単一のメソッドにまとめて，両方のマウスイベントハンドラから呼び出せるようにします。

Adding a method to a form1064039

複数のイベントハンドラに重複するコードがある場合は，そのコードを独立したメソッドにしてイベントハンドラ間で共有すれば，アプリケーションの効率を高められます。

フォームにメソッドを追加する手順は次のとおりです。

1.	フォームオブジェクトにメソッド宣言を追加します。
メソッド宣言は，フォームオブジェクトの宣言の最後にある public 部にも private 部にも追加できます。イベントの処理を部分的に共有するだけならば，メソッドは private 部に入れる方が安全です。

2.	フォームユニットの implementation 部にメソッドを記述します。
メソッドの実装のヘッダーは，宣言と正確に一致させます。パラメータも同じものを同じ順序で記述します。

マウスイベントハンドラから重複する図形描画コードを除去するために，DrawShape というメソッドをフォームに追加し，このメソッドをすべてのイベントハンドラから呼び出します。まず，フォームオブジェクトの宣言に，DrawShape の宣言を追加します。

type

  TForm1 = class(TForm)

    ...	{ ほかのフィールドとメソッドは省略 }

  public

    { Public 宣言 }

    procedure DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);

  end;

次に，ユニットの implementation 部に DrawShapeの実装をします。

implementation

{$R *.FRM}

...	{ ほかの実装部は省略 }

procedure TForm1.DrawShape(TopLeft, BottomRight: TPoint; AMode: TPenMode);

begin

  with Canvas do

  begin

    Pen.Mode := AMode;

    case DrawingTool of

      dtLine:

        begin

          MoveTo(TopLeft.X, TopLeft.Y);

          LineTo(BottomRight.X, BottomRight.Y);

        end;

      dtRectangle: Rectangle(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);

      dtEllipse: Ellipse(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y);

      dtRoundRect: RoundRect(TopLeft.X, TopLeft.Y, BottomRight.X, BottomRight.Y,

        (TopLeft.X - BottomRight.X) div 2, (TopLeft.Y - BottomRight.Y) div 2);

    end;

  end;

end;

最後に，DrawShape を呼び出すように，ほかのイベントハンドラを変更します。

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  DrawShape(Origin, Point(X, Y), pmCopy);	{最後の図形を描画する}

  Drawing := False;

end;

procedure TForm1.FormMouseMove(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Drawing then

  begin

    DrawShape(Origin, MovePt, pmNotXor);	{前に描いた図形を消去する}

    MovePt := Point(X, Y);	{現在の座標を記録する}

    DrawShape(Origin, MovePt, pmNotXor);	{現在の図形を描画する}

  end;

end;


Customizing pens and brushes
Customizing pens and brushes1064040

Section topics	参照

描画に色を加えるには，描画やペイントのためにキャンバスで使用するペンとブラシを変更します。

この節では最初に，アプリケーションにペンとブラシのそれぞれのために，ツールバーを追加します。次に，以下の作業を行う方法を説明します。

ペンスタイルの変更

ペン色の変更

ペン幅の変更

ブラシスタイルの変更

ブラシ色の変更


Changing the pen style
Changing the pen style1064041

Section topics	参照

ペンスタイルでは，ペンで描画される線の種類を指定します。線の種類には，実線，破線，点線などがあります。なお，ディスプレイドライバによっては，ピクセル幅が 2 以上のペンスタイルをサポートしないものもあります。それらのドライバの場合，大きなペン幅の線は，そのスタイルに関係なくすべて実線で表示されます。

ペンスタイルを変更するには次のようにします。

ペンの Style プロパティに線の種類を示す値を設定します。設定できる値は，psSolid，psDash，psDot，psDashDot，psDashDotDot，psClear です。

このサンプルでは，ペンのツールバーにあるペンスタイルボタンごとにクリックイベントハンドラを追加することもできます。しかしここでは，すべてのペンスタイルボタンに単一のイベントハンドラを共有させる方が効率的です。


Sharing an event handler
Sharing an event handler1064042

Section topics	参照

互換性のあるイベントに対しては，同一のイベントハンドラを複数のコントロールで共有できます。互換性のあるイベントとは，これを処理するイベントハンドラが同じパラメータを同じ順序で受け取るようなイベントです。イベントハンドラを共有して使う最も一般的な例は，ある 1 つの処理をさまざまな操作で行えるようにする場合です。たとえば，メニュー項目のクリックイベントとボタンのクリックイベントに同じハンドラを結び付けて，同一の処理を複数の操作方法で実行できるようにします。また，複数のコントロールで同一のハンドラを共有し，呼び出したコントロールによってハンドラに異なる処理を行わせることもできます。

イベントハンドラを共有するには次のようにします。

複数のコントロールのイベントに同一のイベントハンドラを設定します。イベントを実際に取得したコントロールを特定する場合は，Sender パラメータが使用できます。

このサンプルでは，ペンのツールバーにあるすべてのペンスタイルボタンに結び付ける共通のクリックイベントハンドラを作成します。そして Sender を使ってイベントを発生させたボタンを特定します。

1.	6 つのペンスタイルボタンをすべて選択します。

2.	オブジェクトインスペクタの［イベント］ページで OnClick を選択します。

3.	ハンドラ列に SetPenStyle と入力して〔Enter〕を押します。Delphi は SetPenStyle という空のクリックイベントハンドラを生成し，このハンドラを6つのすべてのボタンの OnClick イベントに結び付けます。

4.	Sender の値に応じてペンのスタイルを設定するコードを，クリックイベントハンドラ内に記述します。Sender はクリックイベントを送ったコントロールを示しています。

procedure TForm1.SetPenStyle(Sender: TObject);

begin

  with Canvas.Pen do

  begin

    if Sender = SolidPen then Style := psSolid

    else if Sender = DashPen then Style := psDash

    else if Sender = DotPen then Style := psDot

    else if Sender = DashDotPen then Style := psDashDot

    else if Sender = DashDotDotPen then Style := psDashDotDot

    else if Sender = ClearPen then Style := psClear;

  end;

end;


Changing the pen color
Changing the pen color1064043

Section topics	参照

ペンの色はペンで描画する線の色を決定します。図形の境界として描画される線や多角線の色も，ペンの色で決定されます。

ペンの色を変更するには次のようにします。

ペンの Color プロパティに値を設定します。

このサンプルでは，ユーザーはペンのツールバーのカラーグリッドによってペンの色を指定します。カラーグリッドコントロールは，前景色と背景色の両方を決定する機能を持っています。たとえば，Delphi にはコードを構文によって強調表示する機能がありますが，ここでは前景色と背景色をカラーグリッドを使って指定しています。しかし，このサンプルでは前景色だけを使用します。

ユーザーはカラーグリッドをクリックして新しい色を選択します。したがって，ペンの色はカラーグリッドの OnClick イベントに応答して変更します。

procedure TForm1.PenColorClick(Sender: TObject);

begin

  Canvas.Pen.Color := PenColor.ForegroundColor;

end;


Changing the pen width
Changing the pen width1064044

Section topics	参照

ペン幅はペンで描画する線の太さをピクセル単位で指定します。なお，太さが 1 より大きい場合は，ディスプレイドライバによってはペンの Style プロパティの値に関係なく常に実線を描きます。

ペン幅を変更するには次のようにします。

ペンの Width プロパティに数値を設定します。

このサンプルでは，ペンのツールバーにあるスクロールバーを利用してペン幅の値を設定します。ユーザーにわかるように，スクロールバーの横のラベルも更新します。スクロールバーの位置を利用してペン幅を指定するので，スクロールバーの位置が変更されるたびにペン幅を更新します。

スクロールバーの OnChange イベントを，次のように設述します。

procedure TForm1.PenWidthChange(Sender: TObject);

begin

  Canvas.Pen.Width := PenWidth.Position;	{ペン幅を直接設定する}

  PenSize.Caption := IntToStr(PenWidth.Position);
{キャプションに表示するため，文字列に変換する}

end;


Changing the brush style
Changing the brush style1064045

Section topics	参照

ブラシスタイルでは，キャンバスで図形を塗りつぶすためのパターンを指定します。定義済みのスタイルとして，塗りつぶし，無色，各種の線パターンと格子パターンがあります。

ブラシスタイルを変更するには次のようにします。

ブラシの Style プロパティに定義済みの値を設定します。設定できる値は，bsSolid，bsClear，bsHorizontal，bsVertical，bsFDiagonal，bsBDiagonal，bsCross，bsDiagCross の 8 つです。

このサンプルでは，ペンスタイルを設定したのと同じ方法でブラシスタイルを設定します。つまり，すべてのブラシスタイルボタンで同一のクリックイベントハンドラを共有します。8 つのすべてのブラシスタイルボタンを選択し，オブジェクトエクスプローラの［Event］ページで Onclick ハンドラを選択します。OnClick ハンドラの名前を SetBrushStyle と入力します。

procedure TForm1.SetBrushStyle(Sender: TObject);

begin

  with Canvas.Brush do

  begin

    if Sender = SolidBrush then Style := bsSolid

    else if Sender = ClearBrush then Style := bsClear

    else if Sender = HorizontalBrush then Style := bsHorizontal

    else if Sender = VerticalBrush then Style := bsVertical

    else if Sender = FDiagonalBrush then Style := bsFDiagonal

    else if Sender = BDiagonalBrush then Style := bsBDiagonal

    else if Sender = CrossBrush then Style := bsCross

    else if Sender = DiagCrossBrush then Style := bsDiagCross;

  end;

end;


Changing the brush color
Changing the brush color1064046

Section topics	参照

ブラシ色はキャンバスで図形を塗りつぶすための色を決定します。

ブラシ色を変更するには次のようにします。

ブラシの Color プロパティに値を設定します。

ブラシ色の設定方法はペンの色の場合と同じです。ブラシのツールバーにあるカラーグリッドのクリックに応答します (「ペンの色の変更」を参照してください)。

procedure TForm1.BrushColorClick(Sender: TObject);

begin

  Canvas.Brush.Color := BrushColor.ForegroundColor;

end;


Drawing on a bitmap
Drawing on a bitmap1064047

Section topics	参照

フォームに直接描画することはめったにありません。ほとんどの場合，アプリケーションではビットマップに描画します。ビットマップの方が，コピー，印刷，保存などの操作に柔軟に対応できるからです。Delphi のイメージコントロールコンポーネントはビットマップを入れることができるので，フォームにビットマップを簡単に追加できます。

また，ビットマップの大きさをフォームの大きさと一致させる必要はありません。ビットマップはフォームより大きくすることも小さくすることもできます。フォームにスクロールボックスコントロールを追加し，このコントロール内にイメージを挿入すると，フォームや画面よりも大きいビットマップを作成できます。

描画用のスクロール可能なビットマップを追加するには，以下のステップで行います。

スクロール可能領域の追加

イメージコントロールの追加

イメージコントロール内のビットマップに描画すれば，印刷，クリップボード操作，ビットマップファイルの読み込み，保存が簡単に処理できます。


Adding an image control
Adding an image control1064048

Section topics	参照

イメージコントロールは一種のプレースホルダコンポーネントです。イメージコントロールを使用すると，ビットマップやメタファイルなどの画像オブジェクトを入れる領域をフォームに指定できます。イメージのサイズは，手作業で設定することも，実行時にイメージコントロールで調整することもできます。

イメージコントロールでは，常に表示されている必要のないビットマップや，アプリケーションがほかの画像を生成するために使用するビットマップを保持できます。オーナー描画コントロールで項目を作成するのに使うビットマップを保持するイメージコントロールの使用法は「オーナー描画コントロールの作成」で説明します。

Placing the control1064049

イメージコントロールはフォームのどこにでも配置できます。イメージコントロールのサイズが画像に合わせて自動調整されるように設定することもでき，その場合，配置時には左上隅の位置だけに注意します。ビットマップを入れるための非表示のホルダとしてイメージコントロールを使用する場合は，イメージコントロールはどこに配置してもかまいません。これは，非ビジュアルコンポーネントの場合と同じです。

フォームのクライアント領域に配置したスクロールボックス内にイメージコントロールを追加すると，フォーム内に収まらないイメージでもスクロールバーを使用して表示できるようになります。それからイメージコントロールのプロパティを設定します。

Setting the initial bitmap size1064050

配置したばかりのイメージコントロールには，画像は入っていません。プレースホルダを作成しただけで，表示する内容は指定していないからです。イメージコントロールに常に画像を表示させるには，設計時にイメージコントロールの Picture プロパティを設定します。実行時にイメージコントロールにファイルから画像を読み込むこともできます。この点については「グラフィックファイルの操作」で説明します。描画用の空のビットマップが必要なときは，実行時に作成します。

アプリケーションの起動時に空のビットマップを作成する手順は次のとおりです。

1.	イメージを含むフォームの OnCreate イベントに対してハンドラを結び付けます。

2.	ビットマップオブジェクトを作成し，このオブジェクトをイメージコントロールの Picture.Graphic プロパティに設定します。

このサンプルの場合，イメージはアプリケーションのメインフォーム Form1 にあるので，Form1 の OnCreate イベントにハンドラを結び付けます。

procedure TForm1.FormCreate(Sender: TObject);

var

  Bitmap: TBitmap;	{ビットマップを保持する一時変数}

begin

  Bitmap := TBitmap.Create;	{ビットマップオブジェクトを作成する}

  Bitmap.Width := 200;	{初期の幅を指定する}

  Bitmap.Height := 200;	{初期の高さを指定する}

  Image.Picture.Graphic := Bitmap;	{イメージコントロールにビットマップを設定する} }

end;

Pictureオブジェクトの Graphic プロパティにビットマップを設定すると，ビットマップのオーナーは Picture オブジェクトになります。Picture オブジェクトは使用後のビットマップを自動的に廃棄するので，独自にビットマップオブジェクトを廃棄しないでください。なお，画像には古いビットマップを廃棄して新しいビットマップを設定できます (「画像の置き換え」を参照してください)。

この時点でアプリケーションを実行すると，フォームのクライアント領域にビットマップを示す白い領域が表示されます。ウィンドウのサイズを変更して，クライアント領域にイメージ全体を表示できないようにすると，スクロールボックスが自動的にスクロールバーを表示して，イメージの残りを表示できるようにします。しかし，イメージに描画しようとしてもグラフィックが表示されません。アプリケーションは依然としてフォームに描画するので，描画されたグラフィックはイメージとスクロールボックスの背後に隠れて表示されません。

Drawing on the bitmap1064051

ビットマップに描画するには，次のようにします。

1.	イメージコントロールのキャンバスを使用します。

2.	イメージコントロールの適切なイベントに，マウスイベントハンドラを結び付けます。

このイベントハンドラについては，この章ですでに説明しています。


See also1064052

TCanvas

グラフィックファイルの操作


Creating an owner-draw control
Creating an owner-draw control1071001

Section topics	参照

Windows のリストボックスやコンボボックスコンポーネントは「オーナー描画」というスタイルを使えます。通常のコントロールには Windows の標準の描画方法であるテキストが描画されますが，オーナー描画のコントロールでは，コントロールのオーナー (通常はフォーム) が実行時に各項目を描画します。一般に，オーナー描画コントロールを使用するのは，テキストではなくグラフィックを項目に描画する場合や，テキストに加えてグラフィックも描画する場合などです。このオーナー描画スタイルは，Delphi のタブセットコントロールでも使用できます。

すべてのオーナー描画コントロールに共通する点は，項目のリストを使用することです。デフォルトのリストは文字列のリストであり，これを Windows はテキストとして表示します。Delphi では，オブジェクトにリスト内の各項目を関連付けて，このオブジェクトを利用して項目を描画できます。文字列リストについての詳細は，「文字列リストの操作」を参照してください。

通常，Delphi でオーナー描画コントロールを作成するときは次のステップで行います。

1.	オーナー描画スタイルの設定

2.	文字列リストへのグラフィックオブジェクトの追加

3.	オーナー描画項目の描画


Setting the owner-draw style
Setting the owner-draw style1071002

Section topics	参照

オーナー描画コントロールとして使用できるコントロールには，Styleプロパティがあります。このプロパティでは，コントロールをデフォルト描画 (Standard スタイル) とするかオーナー描画 (OwnerDraw スタイル) とするかを指定します。

リストボックスやコンボボックスのオーナー描画スタイルには，表 22.1 に示すように固定 (Fixed) スタイルと可変 (Variable) スタイルがあります。たとえば，オーナー描画タブセットは常に可変スタイルです。また，オーナー描画グリッドでは各行と各列のサイズは可変にできますが，グリッドを描画する前の各セルのサイズは固定です。

オーナー描画スタイル	説明	例
固定	各項目は ItemHeight プロパティの指定する共通の高さである	lbOwnerDrawFixed， csOwnerDrawFixed
可変	各項目は実行時のデータに応じて高さが変わる	lbOwnerDrawVariable， csOwnerDrawVariable， tsOwnerDraw


Adding graphical objects to a string list
Adding graphical objects to a string list1071003

Section topics	参照

Delphi の各文字列リストは，文字列のリストとは別にオブジェクトのリストも保持できます。つまり文字列リストには，文字列を格納するインデックス付きの Strings プロパティとは別に，Objects プロパティもあります。


Adding images to an application
Adding images to an application1071004

Section topics	参照

イメージコントロールは，ビットマップなどのグラフィックイメージを入れる非ビジュアルコントロールです。イメージコントロールはフォームにグラフィックイメージを表示するのに使いますが，アプリケーションで使用するイメージを非表示状態で保持するためにも使用できます。たとえば，オーナー描画コントロールのビットマップを非表示のイメージコントロールに格納できます。


Adding images to a string list
Adding images to a string list1071005

Section topics	参照

アプリケーションに追加したグラフィックイメージは，文字列リストの文字列と関連付けることができます。グラフィックイメージオブジェクトは，文字列と同時に追加することも，追加済みの文字列に後から関連付けることもできます。必要なデータがすべてある場合は，文字列とオブジェクトを同時に追加します。


Drawing owner-draw items
Drawing owner-draw items1071006

Section topics	参照

コントロールのスタイルをオーナー描画にすると，Windows は画面にコントロールを描画しなくなります。かわりに，コントロールに表示されている項目ごとにイベントを生成します。アプリケーションでこのイベントを処理し，各項目を描画します。

オーナー描画コントロールの項目を描画するステップは，次のとおりです。コントロールに表示されている各項目ごとに，ステップが繰り返されます。ただし，すべての項目は共通な 1 つのイベントハンドラを使用します。

オーナー描画コントロール内の項目を描画するには，

1.	オーナー描画項目のサイズ変更
このステップは，すべてのオーナー描画項目が同じサイズであれば必要ありません。たとえば，リストボックスでスタイルが lsOwnerDrawFixed である場合などです。

2.	オーナー描画項目の描画


Sizing owner-draw items
Sizing owner-draw items1071007

Section topics	参照

アプリケーションで可変オーナー描画コントロールに各項目を描画する前に，Windows は項目のサイズを取得するイベントを生成します。このイベントによって，アプリケーションはコントロール上に項目を表示する位置を知ることができます。

Windows は，項目のテキストを現在のフォントで表示できる大きさか判断します。アプリケーションはイベントを処理することで Windows が判断した四角形のサイズを変更できます。たとえば，テキストのかわりにビットマップを項目に表示する場合，ビットマップのサイズに合わせてサイズを変更できます。ビットマップとテキストの両方を表示する場合は，両方を合わせた四角形のサイズにします。

オーナー描画項目のサイズを変更するには次のようにします。

オーナー描画コントロールの項目のサイズを取得するイベントに対して，イベントハンドラを結び付けます。

イベントの名前はオーナー描画コントロールによって異なります。リストボックスとコンボボックスでは OnMeasureItem です。タブセットでは OnMeasureTab です。グリッドにはサイズ取得イベントはありません。

サイズ取得イベントには，2 つの重要なパラメータがあります。項目のインデックス番号と項目のサイズです。サイズは可変であり，アプリケーションで大きくしたり小さくしたりできます。先行する項目のサイズによって，後続の項目の位置が決まります。

たとえば，可変オーナー描画リストボックスで最初の項目の高さを 5 ピクセルに設定すると，2 番目の項目は上端から 6 ピクセル目に配置されます。以下同様です。リストボックスとコンボボックスの場合，アプリケーションで変更できるのは項目の高さだけです。項目の幅は常にコントロールの幅になります。タブセットの場合は，コントロールの高さでタブの高さが決まるので，変更できるのはタブの幅だけです。

メモ	オーナー描画グリッドでは，描画時にセルのサイズを変更することはできません。各行と各列のサイズは，ColWidths と RowHeights の両プロパティで描画前に設定します。

例

次のコードは，オーナー描画のタブセットの幅を調整し，デフォルトのテキストとビットマップを処理しています。

タブセットの場合，各タブのデフォルトの幅はタブのテキストの幅です。テキストの横にビットマップを追加するには，サイズ取得イベントを処理し，タブ幅の値を増やしてテキストとビットマップの両方が入るだけのスペースを確保する必要があります。

タブ幅を広くしてタブに関連付けたビットマップも表示するために，オーナー描画タブセットの OnMeasureTab イベントに対して，次のコードを結び付けます。

procedure TFMForm.DriveTabSetMeasureTab(Sender: TObject; Index: Integer;

  var TabWidth: Integer);	{TabWidth は var パラメータであることに注意}

var

  BitmapWidth: Integer;

begin

  BitmapWidth := TBitmap(DriveTabSet.Tabs.Objects[Index]).Width;
{関連付けられたビットマップの幅に 2 を加えた値だけタブ幅を増やす}

  Inc(TabWidth, 2 + BitmapWidth);

end;

メモ	文字列リストの Objects プロパティの項目は型キャストしなければなりません。Objects は TObject 型のプロパティなので，すべての種類のオブジェクトを保持できます。配列から取り出したオブジェクトは，型キャストして実際の型に戻します。


Drawing each owner-draw item
Drawing each owner-draw item1071008

Section topics	参照

オーナー描画コントロールをアプリケーションで描画または再描画しなければならないときは，Windows はコントロールに表示されている項目ごとに項目を描画するイベントを生成します。

オーナー描画コントロールの各項目を描画するには次のようにします。

このコントロールの項目を描画するイベントに対して，イベントハンドラを結び付ける

項目描画イベントの名前は必ず OnDraw で始まり，たとえば OnDrawItem，OnDrawTab，OnDrawCell のようになっています。

項目描画イベントは，描画する項目のインデックスと描画領域の矩形をパラメータとして持っています。さらに通常は，項目にフォーカスがあるかどうかなど，項目の状態を示すパラメータも持ちます。アプリケーションはイベントを処理して，指定の矩形に適切な項目を描画します。

例

たとえば，文字列とビットマップを持つタブをタブセットに描画するには，タブセットの OnDrawTab イベントに対して，次のイベントハンドラを結び付けます。

procedure TFMForm.DriveTabSetDrawTab(Sender: TObject; TabCanvas: TCanvas;

  R: TRect; Index: Integer; Selected: Boolean);

var

  Bitmap: TBitmap;

begin

  Bitmap := TBitmap(DriveTabSet.Tabs.Objects[Index]);

  with TabCanvas do

  begin

    Draw(R.Left, R.Top + 4, Bitmap);	{ビットマップを描画する}

    TextOut(R.Left + 2 + Bitmap.Width,	{テキストを挿入し，}

      R.Top + 2, DriveTabSet.Tabs[Index]);	{ビットマップの右側に描画する}

  end;

end;

メモ	項目を描画するほとんどのイベントでは，パラメータとしてキャンバスオブジェクトを渡すことはありません。通常は描画先のコントロールのキャンバスを使用するからです。しかし，タブセットでは項目間にタブセパレータも描画するので，パラメータとして項目を描画するためのキャンバスを渡します。


See also1071009

TComboBox

TDBComboBox

TListBox

TDBListBox

TDBLookupComboBox

TDBLookupListBox


Working with graphics files
Working with graphics files1065001

Section topics	参照

アプリケーションを終了するとグラフィックイメージが失われてしまうようでは，あまり便利ではありません。同じ画像を毎回使用したり，作成した画像を保存して後で再利用したい場合が多いはずです。Delphi のイメージコントロールを使用すると，簡単に画像をファイルから読み込んだり，ファイルへ保存することができます。

グラフィックファイルの読み込み，保存を行う全体的なロジックはほかのファイルの場合と共通なので，この節では詳しく説明しません。この章では，グラフィックオブジェクトがファイルを読み込み，保存する機能について，以下の点を説明します。

ファイルからの画像の読み込み

ファイルへの画像の保存

画像の置き換え

この章では，クリップボードを使ったグラフィックの操作についても解説します。


Loading a picture from a file
Loading a picture from a file1065002

Section topics	参照

ファイルから画像を読み込む機能は 2 つの場合に重要です。1 つはアプリケーションで画像を変更する場合です。もう 1 つは，ユーザーやほかのアプリケーションがコードを変更せずに画像を変更できるように，画像をアプリケーション外に保存する場合です。

グラフィックファイルをイメージコントロールへ読み込むには次のようにします。

イメージコントロールの Picture オブジェクトの LoadFromFile メソッドを呼び出す

次の例では，［ファイルを開く］ダイアログボックスでファイル名を取得してから，Image という名前のイメージコントロールにファイルを読み込みます。

procedure TForm1.Open1Click(Sender: TObject);

begin

  if OpenDialog1.Execute then

  begin

    CurrentFile := OpenDialog1.FileName;

    Image.Picture.LoadFromFile(CurrentFile);

  end;

end;


Saving a picture to a file
Saving a picture to a file1065003

Section topics	参照

作成または変更した画像は，ファイルに保存して後で再利用できれば便利です。Delphi の Picture オブジェクトは，グラフィックを複数の形式で保存できます。また Picture オブジェクトは，アプリケーション開発者が独自に作成して登録したグラフィックファイル形式も扱えます。

イメージコントロールの内容をファイルに保存するには次のようにします。

イメージコントロールの Picture オブジェクトの SaveToFile メソッドを呼び出す

SaveToFile メソッドには保存先のファイルの名前を指定します。新しく作成した画像はファイル名を持っていない場合もあり，また既存の画像でもユーザーがほかの名前で保存する場合があるからです。どちらの場合も，アプリケーションはファイルの保存前にユーザーからファイル名を取得しなければなりません (次の節を参照)。

次の 2 つのイベントハンドラを，［ファイル(F)｜上書き保存(S)］メニュー項目と［ファイル(F)｜名前を付けて保存(A)］メニュー項目にそれぞれ結び付けます。この 2 つのイベントハンドラで，名前を持つファイルの再保存，名前を持たないファイルの保存，名前を持つファイルの別名での保存を処理します。

procedure TForm1.Save1Click(Sender: TObject);

begin

  if CurrentFile <> '' then

    Image.Picture.SaveToFile(CurrentFile)	{すでに名前があれば保存する}

  else SaveAs1Click(Sender);	{そうでなければ名前を取得する}

end;

procedure TForm1.Saveas1Click(Sender: TObject);

begin

  if SaveDialog1.Execute then	{ファイル名を取得する}

  begin

    CurrentFile := SaveDialog1.FileName;	{ユーザーが指定した名前を保存する}

    Save1Click(Sender);	{通常のとおりに保存する}

  end;

end;


Replacing the picture
Replacing the picture1065004

Section topics	参照

イメージコントロールの画像はいつでも置き換えられます。すでにグラフィックが設定されている画像に，新しいグラフィックを設定すると，既存のグラフィックは新しいグラフィックに置き換わります。

イメージコントロールの画像を置き換えるには次のようにします。

イメージコントロールの Picture オブジェクトに新しいグラフィックを設定する

新しいグラフィックを作成する方法は，最初のグラフィックを作成した方法と同じです (「ビットマップの初期サイズの設定」を参照)。ただし，最初のグラフィックのサイズとは異なるサイズをユーザーが選択できるようにします。このようなオプションを提供するためには，次のようなダイアログボックスを使用します。

プロジェクトでこのダイアログボックスを使用して，メインフォームのユニットの uses 節に BMPDlg を追加します。次に，［File｜New］メニュー項目の OnClick イベントに対して，次のイベントハンドラを結び付けます。

procedure TForm1.New1Click(Sender: TObject);

var

  Bitmap: TBitmap;	{新しいビットマップの一時変数}

begin

  with NewBMPForm do

  begin

    ActiveControl := WidthEdit;	{［Width］フィールドにフォーカスを与える}

    WidthEdit.Text := IntToStr(Image.Picture.Graphic.Width);	{現在の寸法を...}

    HeightEdit.Text := IntToStr(Image.Picture.Graphic.Height);	{...デフォルトとして使用する}

    if ShowModal <> idCancel then	{ユーザーがダイアログボックスをキャンセルしなければ続行する}

    begin

      Bitmap := TBitmap.Create;	{新しいビットマップオブジェクトを作成する}

      Bitmap.Width := StrToInt(WidthEdit.Text);	{指定の幅を使用する}

      Bitmap.Height := StrToInt(HeightEdit.Text);	{指定の高さを使用する}

      Image.Picture.Graphic := Bitmap;	{新しいビットマップでグラフィックを置き換える}

      CurrentFile := '';	{ファイル名が未定であることを示す}

     end;

  end;

end;

重要なことは，画像の Graphic プロパティに新しいビットマップを設定すると，画像オブジェクトは既存のビットマップを廃棄して新しいビットマップのオーナーになることです。前のビットマップに関連付けられていたリソースの解放は，Delphi が自動的に処理します。


Using the Clipboard with graphics
Using the Clipboard with graphics1065005

Section topics	参照

Windows のクリップボードを使って，アプリケーション内でグラフィックをコピーして貼り付けたり，ほかのアプリケーションとグラフィックを交換したりできます。Delphi のクリップボードオブジェクトでは，グラフィックを含むさまざまな種類の情報を簡単に処理できます。

アプリケーションでクリップボードオブジェクトを使用する前に，クリップボードデータにアクセスするユニットの uses 節に Clipbrd ユニットを追加します。


Copying graphics to the Clipboard
Copying graphics to the Clipboard1065006

Section topics	参照

クリップボードには，イメージコントロールの内容を含めてすべての画像をコピーできます。クリップボードに入れた画像は，すべての Windows アプリケーションで利用できます。

クリップボードに画像をコピーするには次のようにします。

Assign メソッドを使用してクリップボードオブジェクトに画像を設定します。

このサンプルでは，［Edit｜Copy］メニュー項目のクリックに応答して，クリップボードに Image という名前のイメージコントロールの画像をコピーする方法を示します。

procedure TForm1.Copy1Click(Sender: TObject);

begin

  Clipboard.Assign(Image.Picture);

end;


Cutting graphics to the Clipboard
Cutting graphics to the Clipboard1065007

Section topics	参照

クリップボードへのグラフィックの切り取りはコピーと似ていますが，元のグラフィックを消去する点だけが異なります。

画像からグラフィックを切り取ってクリップボードに入れるには次のようにします。

最初にグラフィックをクリップボードにコピーし，次に元のグラフィックを消去します。

ほとんどの場合，切り取りで問題なのは，元のイメージの消去後の処理です。一般には，その領域を白色にします。このサンプルでは，［Edit｜Cut］メニュー項目の OnClick イベントに対して，次のイベントハンドラを結び付けます。

procedure TForm1.Cut1Click(Sender: TObject);

var

  ARect: TRect;

begin

  Copy1Click(Sender);	{画像をクリップボードにコピーする}

  with Image.Canvas do

  begin

    CopyMode := cmWhiteness;	{すべてに白色をコピーする}

    ARect := Rect(0, 0, Image.Width, Image.Height);	{ビットマップの四角形を取得する}

    CopyRect(ARect, Image.Canvas, ARect);	{ビットマップをそれ自身にコピーする}

    CopyMode := cmSrcCopy;	{通常のモードに戻る}

  end;

end;


Pasting graphics from the Clipboard
Pasting graphics from the Clipboard1065008

Section topics	参照

Windows のクリップボードにビットマップ形式のグラフィックがあれば，これをイメージコントロールやフォームの表面などのイメージオブジェクトに貼り付けることができます。

クリップボードからグラフィックを貼り付ける手順は次のとおりです。

1.	クリップボードの HasFormat メソッドを呼び出し，クリップボードにグラフィックがあるかどうかを確認します。
HasFormat は論理関数です。パラメータで指定された種類のデータがクリップボードにあれば True を返します。ビットマップがあるかどうかをテストするには，パラメータに CF_BITMAP を指定します。

2.	貼り付け先のオブジェクトにクリップボードを設定します。

この例では，［Edit｜Paste］メニュー項目のクリックに応答して，クリップボードのビットマップをイメージコントロール内に貼り付けます。

procedure TForm1.PasteButtonClick(Sender: TObject);

var

  Bitmap: TBitmap;

begin

  if Clipboard.HasFormat(CF_BITMAP) then	{クリップボードにビットマップがあるかどうかチェックする}

  begin

    Bitmap := TBitmap.Create;	{クリップボードの内容を保持するビットマップを作成する}

    try

      Bitmap.Assign(Clipboard);	{クリップボードからビットマップを取得する}

      Image.Canvas.Draw(0, 0, Bitmap);	{ビットマップを Image にコピーする}

    finally

      Bitmap.Free;

    end;

  end;

end;


See also1065009

グラフィックの印刷

開くファイルの選択

TOpenPictureDialog

ファイルの保存

TSavePictureDialog

TClipboard


Manipulating files
Manipulating files1063001

Section topics	参照

Object Pascal のランタイムライブラリには，いくつかの共通のファイル操作が組み込まれています。ファイルを操作する手続きや関数は上位レベルで動作します。ファイル名を指定して手続きや関数を呼び出すと，呼び出された手続きや関数はさらにオペレーティングシステムに対して必要な呼び出しを行います。さらに，DEMOS\DOC\FILMANEX ディレクトリには追加のルーチンの例が入っています。ソースコードを調べて，たとえばファイルのコピーや移動をしたり，個々のファイルのサイズを返したりするルーチンの例を見ることができます。

Pascal 言語の古いバージョンでは，共通のファイル操作を，ファイル名に対してではなくファイル自体に対して行っていました。たとえばファイルの名前を変更する場合でも，対象のファイルをいったんファイル変数に代入しなければなりませんでした。これに対して，Object Pascal は上位レベルで動作するため，コードの記述が簡単になり，アプリケーションは簡素化されます。以前の下位レベルで動作する関数も使用できますが，通常は必要ではありません。

Object Pascal のアプリケーションで利用できるファイル操作は，以下のとおりです。

ファイルの削除

ファイル属性の変更

ファイルの移動，コピー，名前の変更

ほかのアプリケーションの実行


Deleting a file
Deleting a file1063002

Section topics	参照

削除したファイルはディスクから消去され，またディスクのディレクトリからも除去されます。一般には削除したファイルは復元できないので，通常，アプリケーションではファイルを削除することをユーザーに確認します。

ファイルを削除するには次のようにします。

ファイルの名前を DeleteFile 関数に渡す

DeleteFile は，ファイルを削除すると True を返します。ファイルが存在しないか，または読み出し専用であるためにファイルを削除しなかった場合は False を返します。

Example1063003

次のコードでは，［File｜Delete］メニュー項目のクリックに応答してファイルリストボックスの選択ファイルを削除し，この削除を反映させるためにリストを更新します。

procedure TFMForm.Delete1Click(Sender: TObject);

begin

  with FileList do

    if DeleteFile(FileName) then Update;

end;


Changing a file's attributes
Changing a file's attributes1063004

Section topics	参照

各ファイルのさまざまな属性は，ビットごとに割り当てられたフラグとしてオペレーティングシステムに格納されています。ファイルの属性とは，ファイルが読み出し専用かどうか，隠しファイルかどうかなどです。

ファイル属性の変更は次のステップで行います。

1.	ファイル属性の取得

2.	ファイル属性の変更

3.	ファイル属性の設定

ファイルの属性を取得するだけの場合や，以前の設定とは関係なく属性を設定する場合は，取得操作または設定操作を単独で行えます。以前の設定に従って属性を変更する場合は，取得操作と設定操作を両方使用します。つまり，既存の属性を取得して変更し，変更した属性を設定します。


Reading file attributes
Reading file attributes1063005

Section topics	参照

オペレーティングシステムがファイル属性を格納する方式はさまざまですが，通常はビットごとに割り当てられたフラグとして格納します。

ファイルの属性を取得するには次のようにします。

ファイル名を FileGetAttr 関数に渡します。

この関数は Word 型のビットごとに割り当てられたファイル属性を戻り値とします。


Changing individual file attributes
Changing individual file attributes1063006

Section topics	参照

Delphi はファイル属性を 1 つにまとめて示します。個々の属性は通常のビット演算子で操作できます。各属性は SysUtils ユニットで名前が定義されています。

たとえば，ファイルの読み出し専用属性を設定する代入文は，次のとおりです。

Attributes := Attributes or faReadOnly;

複数の属性を同時に設定またはクリアすることもできます。たとえば，システムファイル属性と隠しファイル属性の両方をクリアする代入文は，次のとおりです。

Attributes := Attributes and not (faSysFile or faHidden);


Setting file attributes
Setting file attributes1063007

Section topics	参照

Delphi では，任意のファイルに任意の時点で属性を設定できます。

ファイルの属性を設定するには次のようにします。

ファイルの名前と設定する属性を手続き FileSetAttr に渡す

Example1063008

次のコードでは，ファイルの属性を1つの変数に代入し，［File Attributes］ダイアログボックスで現在の属性を示すチェックボックスを設定し，このダイアログボックスを実行します。ユーザーがダイアログボックスで設定を変更すると，この変更に従ってファイル属性を設定します。

procedure TFMForm.Properties1Click(Sender: TObject);

var

  Attributes, NewAttributes: Word;

begin

  with FileAttrForm do	{フォームが前に作成した属性}

  begin

    FileDirName.Caption := FileList.Items[FileList.ItemIndex];
{ボックスのキャプションを設定する}

    FilePathName.Caption := FileList.Directory;	{ディレクトリ名を表示する}

    ChangeDate.Caption := DateTimeToStr(FileDateToDateTime(FileAge(FileList.FileName)));

    Attributes := FileGetAttr(FileDirName.Caption);	{ファイル属性を取得する}

    ReadOnly.Checked := (Attributes and faReadOnly) = faReadOnly;

    Archive.Checked := (Attributes and faArchive) = faArchive;

    System.Checked := (Attributes and faSysFile) = faSysFile;

    Hidden.Checked := (Attributes and faHidden) = faHidden;

    if ShowModal <> mrCancel then	{ダイアログボックスを実行する}

    begin

      NewAttributes := Attributes;	{元の属性値から始める}

      if ReadOnly.Checked then NewAttributes := NewAttributes or faReadOnly

      else NewAttributes := NewAttributes and not faReadOnly;

      if Archive.Checked then NewAttributes := NewAttributes or faArchive

      else NewAttributes := NewAttributes and not faArchive;

      if System.Checked then NewAttributes := NewAttributes or faSysFile

      else NewAttributes := NewAttributes and not faSysFile;

      if Hidden.Checked then NewAttributes := NewAttributes or faHidden

      else NewAttributes := NewAttributes and not faHidden;

      if NewAttributes <> Attributes then	{変更があれば...}

        FileSetAttr(FileDirName.Caption, NewAttributes);
{...新しい値を書き込む}

    end;

  end;

end;


Moving, copying, and renaming files
Moving, copying, and renaming files1063009

Section topics	参照

ファイルの移動，コピー，名前の変更という 3 つの操作は，あるファイルから別のファイルを作成するという点では共通しています。しかし，3 つの操作は元のファイルに対する処理が異なります。コピーでは元のファイルを一切変更しません。名前の変更では元のファイルの名前を変更します。移動では元のファイルを新しい位置にコピーした後，削除します。

ランタイムライブラリには，名前の変更を処理するルーチン RenameFile があります。FMXUtils ユニットには，移動を処理するルーチン MoveFile とコピーを処理するルーチン CopyFile があります。各ルーチンは，元のファイル名と新しいファイル名の 2 つの文字列パラメータを使用します。アプリケーションでは，3 つの操作を 1 つのメソッドで簡単に処理できます。

次のコードは ConfirmChange メソッドを記述します。このメソッドは確認のためのダイアログボックスを表示し，確認されると指定の操作を実施します。

procedure TFMForm.ConfirmChange(const ACaption, FromFile, ToFile: string);

begin

  if MessageDlg(Format('%s %s to %s?', [ACaption, FromFile, ToFile]),

    mtConfirmation, [mbYes, mbNo], 0) = mrYes then

  begin

    if ACaption = 'Move' then

      MoveFile(FromFile, ToFile)

    else if ACaption = 'Copy' then

      CopyFile(FromFile, ToFile)

    else if ACaption = 'Rename' then

      RenameFile(FromFile, ToFile);

    FileList.Update;

  end;

end;


Executing an application
Executing an application1063010

Section topics	参照

あるアプリケーションからほかのアプリケーションを実行することがよくあります。特定の作業を行うことを目的とする場合もあれば，単にほかのアプリケーションを同時に実行することを目的とする場合もあります。アプリケーションを実行するには，Windows API の提供する ShellExecute 関数も使用できますが，この関数は Delphi アプリケーションでは不要なパラメータをいくつも使用します。FMXUtils ユニットには，ShellExecute 関数よりもはるかに便利な ExecuteFile 関数があります。

ExecuteFile は 2 種類の動作を行います。第 1 に，実行形式ファイルの名前を渡すと，このファイルを実行します。第 2 に，アプリケーションに関連付けられた文書の名前を渡すと，アプリケーションを実行して文書を自動的に開きます。


Executing a file from a file list box
Executing a file from a file list box1063011

Section topics	参照

ExecuteFile は 4 つのパラメータを使用します。最初の 3 つのパラメータは文字列パラメータであり，ファイル名，アプリケーションに渡すコマンドラインパラメータ，実行時のディレクトリの名前をそれぞれ示します。4 番目のパラメータでは，実行したアプリケーションをウィンドウに表示する方法を指定します。

4 番目のパラメータには，API 関数 ShowWindow で使用する Windows 定数を指定します。たとえば，ウィンドウを通常の形式で表示する SW_SHOW や，ウィンドウをアイコン表示する SW_SHOWMINIMIZED などを指定します。

Example1063012

ファイルリストボックスは，リストのファイルを実行するのに必要なすべての情報を含んでいます。次の簡単なコードは，ファイルリストボックスで現在選択されているファイルを ExecuteFile で実行します。

procedure TFMForm.Open1Click(Sender: TObject);

begin

  with FileList do

    ExecuteFile(FileName, '', Directory, SW_SHOW);

end;

しかし上記のような場合，必ずファイルを実行するものとは限りません。選択されている項目がディレクトリであれば，それを実行することはできません。ディレクトリの場合は，このアプリケーションでは，それを開いてディレクトリを変更します。

次に示すコードは，ディレクトリをファイルとは異なる方法で処理するようにした Open1Click です。

procedure TFMForm.Open1Click(Sender: TObject);

begin

  with FileList do

  begin

    if HasAttr(FileName, faDirectory) then

      DirectoryOutline.Directory := FileName

    else ExecuteFile(FileName, '', Directory, SW_SHOW);

  end;

end;


See also1063013

開くファイルの選択

ファイルの保存

TSavePictureDialog

TClipboard


Using OLE Automation
Using OLE Automation1069001

Section topics	参照

OLE オートメーションは，アプリケーションが別のアプリケーションや DLL にあるオブジェクトにアクセスするためのプロトコルです。このオブジェクトにアクセスすると，次のことができます。

アプリケーションや DLL の動作の制御

アプリケーションや DLL の機能へのアクセス

自動化されるアプリケーションはオートメーションサーバーと呼ばれます。別のアプリケーションを自動化するアプリケーションは，オートメーションコントローラまたはクライアントです。アプリケーションは，サーバーであると同時にコントローラでもあります。

この章では，高度な Delphi オブジェクトを使って OLE オートメーションのサーバーとクライアントを作成します。OLE オートメーションのサーバーとクライアントの作成は難しくありませんが，関連する機能が数多くあるため，意外と複雑かもしれません。したがって，大規模な OLE オートメーションを使うために必要なキーとなる技術についても説明してあります。

この章では，以下のことについて説明します。

CreateOleObject 関数による OLE オブジェクトの作成

OLE オブジェクトをカプセル化するバリアント型変数の使い方

OLE クライアント

バリアント型配列


About OLE Automation
About OLE Automation1069002

Section topics	参照

OLE オートメーションを使うと，自分のプログラムにあるオブジェクトだけでなく，システム内のほかのプログラムにあるオブジェクトにもアクセスできます。オブジェクトの実際のデータにはアクセスできませんが，オブジェクトのメソッドやプロパティにアクセスできます。アクセスする場合，オブジェクトの実現に使ったプログラミング言語は関係ありません。将来 Network OLE が導入されると，この機能によってネットワーク上の複数のマシンに拡張して，分散アプリケーションを作成することができるでしょう。

OLE オートメーションには以下の 2 種類があります。

OLE オートメーションサーバー

OLE オートメーションクライアント (コントローラ)

オートメーションサーバーは，オートメーションクライアントからアクセスできる機能を提供します。つまり，オブジェクトを提供するアプリケーションまたは DLL がサーバーであり，オブジェクトにアクセスするアプリケーションまたは DLL がクライアントです。Delphi では，アプリケーションや DLL をいろいろなアプリケーションと自由に統合して OLE オートメーションのサーバーやクライアントにできます。

Microsoft 社の Word や Excel は OLE オートメーションサーバーの一例です。どちらのアプリケーションも，Delphi アプリケーションやほかのオートメーションクライアントによって制御できます。OLE オートメーションサーバーについての詳細は『開発者ガイド』の「OLE オートメーション」を参照してください。


A simple OLE Automation client
A simple OLE Automation client1069003

Section topics	参照

OLE オートメーションサーバーの代表として，Microsoft Word があります。Word 6.X またはWord 7.X をシステムにインストールしている場合，次のコードを implementation 部に入力することで Delphi アプリケーションから Word にアクセスできます。

uses OleAuto;

procedure TForm1.Button1Click(Sender: TObject);

var

  V: Variant

begin

  V := CreateOleObject('Word.Basic');

  V.Insert('Hello from Delphi');

end;

このコードは，この時点で開いている Word の文書に「Hello from Delphi」というテキストを挿入します。先に Word を起動して適当な文書を開いていないと，このコードは正しく機能しません。Word をまだ起動していない場合の手順については後述します。

このコードには 3 つの重要な要素があります。1 つは uses 節に示された OleAuto ユニットです。このユニットには，Delphi アプリケーションの内部でオートメーションを処理するためのすべての主要なコードが記述されています。

2 つ目の要素はバリアント型変数です。OLE オートメーションでは広い範囲に渡ってバリアント型を使うため，Object Pascal でもバリアント型を使えるようになりました。バリアント型はオートメーションに不可欠ではありませんが，Microsoft 社の提供する OLE を利用する場合は，バリアント型を使うことでオートメーション操作が簡単になります。

V := CreateOleObject('Word.Basic');

このコードは，OLE オブジェクトをバリアント型の V に割り当てます。OLE オブジェクトは Word に属します。つまり，Word は OLE オートメーションサーバーです。

コードの 3 つ目の要素は，Word Basic の Insert メソッド呼び出しです。

V.Insert('Hello from Delphi');

Insert は Object Pascal のメソッドでも関数でもなければ，Windows API の一部でもありません。これは Word の一部であり，OLE オートメーションを使って Delphi アプリケーションの内部から直接呼び出せます。


Variants as OLE objects
Variants as OLE objects1069004

Section topics	参照

バリアント型の種類を調べるには，バリアント型を TVarData レコードに型キャストし，その VType フィールドを調べるか，または VarType 関数を呼び出します。特にバリアント型が OLE オブジェクトの場合，その VType フィールドまたは VarType 関数の戻り値には varDispatch が設定されます。

バリアント型オブジェクトの種類を確認するには，次のコードを使います。

V := CreateOleObject('Word.Basic');

if VarType(V) = VarDispatch then

  ShowMessage('Yes')

else

  ShowMessage('No');

TVarData の Vtype フィールドを varByte または varString などと比較すると，「No」が表示されるでしょう。これは，V が IDispatch 型のオブジェクトを参照していることを示しています。IDispatch オブジェクトそのものを取得したい場合は次のようにしますが，これはなるべく行わないでください。

A := VarToInterface(V);

A.AddRef;

A.GetTypeInfoCount(i);

ShowMessage(IntToStr(i));

A.Release;

VarToInterface 関数は OleAuto ユニットに実装されています。この関数では，まず有効な IDispatch インターフェースがバリアント型に含まれているかどうか確認します。含まれていれば，次のコードを実行することでインターフェースを返します。

Result := TVarData(V).VDispatch;

上記の例では，IDispatch のメソッドである GetTypeInfoCount を呼び出しています。通常は値 1 を返します。このコードは，IDispatch インターフェースへのハンドルを持っていることを示すために加えただけです。

VarToInterface に関連したもう 1 つの関数に VarToAutoObject があります。このルーチンは IDispatch インターフェースのかわりに，IDispatch オブジェクトを処理するための Delphi オブジェクトである TAutoObject を返します。

バリアント型の値を UnAssigned または Null に設定することもできます。たとえば，次のようなコードにします。

var

  MyVariant: Variant;

begin

  MyVariant := CreateOleObject('Word.Basic');

  ...

  MyVariant := UnAssigned;

end;

このコードは，最初に OLE オブジェクトを取得してから，それを解放します。このようなコードは，見つけたオブジェクトがエラー状態であることがわかった場合や，そのサービスが不要になった場合などにオブジェクトを解放するのに使えます。

UnAssigned はバリアント型の変数で，System ユニットで宣言されています。


OLE Automation and the registry
OLE Automation and the registry1069005

Section topics	参照

CreateOleObject を呼び出すときには，文字列を渡します。この文字列のことを，プログラム ID または ProgID と呼びます。たとえば，Word.Basic という文字列は Microsoft Word の持つ OLE オートメーションサーバーの ProgID です。プログラム ID とはレジストリで検索できる文字列で，CLSID を参照します。CLSID とはオブジェクトごとに重複しない番号で，オペレーティングシステムが OLE オブジェクトを参照するのに使います。

CreateOleObject を呼び出すと Windows は Word がメモリに読み込まれているかどうかを調べ，そうでなければ上記のコマンドラインを渡して Word を起動します。次に，要求された OLE オートメーションオブジェクトへのインターフェースつまりポインタを探し，それを CreateOleObject への呼び出しの結果として返します。つまり，Word そのものへのポインタではなく，Word 内にあるオブジェクトへのポインタだけが返されます。

Word 内にある OLE オートメーションオブジェクトへのインターフェースを入手すれば，OLE オートメーションオブジェクトによって関数を呼び出せます。Word オンラインヘルプにある Word Basic 関数はすべて使えます。このような関数は 200 個ほどあり，文書の開/閉，保存，書式設定，印刷などのためのコマンドが入っています。


Running an OLE Automation server in the background
Running an OLE Automation server in the background1069006

Section topics	参照

Word が起動されていない状態で文書に何か挿入したい場合は，次のコードを使用します。

procedure TForm1.Button1Click(Sender: TObject);

begin

  V := CreateOleObject('Word.Basic');

  V.FileNew('Normal');

  V.Insert('The mark of a healthy mind' + #13);

  V.Insert('is freedom from its own ideas.');

  V.FileSaveAs('C:\SEMPERFI.DOC');

end;

注目すべき点は，Word が画面に表示されないことです。Word は一時的にメモリに読み込まれます。ただし表示はされません。変数 V のスコープ外に出るか，または varNothing に設定されると，Word は終了します。ハードディスクの駆動音が聞こえる以外に，このコードが動作したことを確認するには，実行後に Word を起動し，SEMPERFI.DOC を開いて，文字列が挿入されていることを調べるしかありません。

このコードでは最初に CreateOleObject を呼び出します。このコード行は，Word がまだ起動していなければ，Word に /Automation パラメータを付けて起動します。Word はこのパラメータに基づいて，いつ起動したかということと，見えない状態のバックグラウンドで実行しなければならないことを認識します。サービスする  OLE オートメーションクライアントがなくなると，Word は自分で終了します。

テキストに改行文字 (#13) を挿入してこれらの行に復帰動作を追加することもできます。

Word がOLE オートメーションクライアントによりメモリに呼び出されてバックグラウンドで 実行されるのは単なる偶然の一致ではありません。実際，OLE オートメーションクライアントは，OLE オートメーションコントローラではなくユーザーが起動する場合を除いて，OLE オートメーションサーバーを通常バックグラウンドで実行するように定義されています。


OLE Parameters: named and positional
OLE Parameters: named and positional1069007

Section topics	参照

FileNew コマンドや FileSaveAs コマンドは Word ヘルプで検索できる標準的な Word Basic 手続きです。これらのコマンドの機能は説明するまでもありませんが，Word ヘルプで FileSaveAs を検索すると，次のリストが表示されます。

FileSaveAs [.Name = text] [, .Format = number] [, .LockAnnot = number] [, .Password = text] [, .AddToMru = number] [, .WritePassword = text] [, .RecommendReadOnly = number] [, .EmbedFonts = number] [, .NativePictureFormat = number] [, .FormsData = number] [, .SaveAsAOCELetter = number]

見たとおり，FileSaveAs には Name，Format，LockAnnot，Password，AddToMru，WritePassword，RecommendReadOnly，EmbedFonts，NativePictureFormat，FormsData，SaveAsAOCELetter の合計 11 個のパラメータがあります。11 個もパラメータがある場合，呼び出した関数にどのようにして 1 つのパラメータだけを渡すのでしょう。

ここでのポイントは，Word ではオプションのパラメータをサポートするという点です。前述のコードでは 1 つのパラメータだけをオブジェクトに渡していますが，次のように指定すれば，2 つのパラメータを渡すこともできます。

V.FileSaveAs('C:\SEMPERFI.TXT', 3);

このコードでは，2 番目のパラメータでファイルの種類を指定しています。Format パラメータには以下のいずれかの値を使用できます。

パラメータ	意味
0	Word 文書
1	文書テンプレート
2	テキストのみ
3	テキストのみと改行
4	MS-DOS テキスト (IBM PC 文字セットに保存される拡張文字)
5	改行付き MS-DOS テキスト
6	書式付きテキスト
パラメータを定義する順は決まっていません。たとえば，次のようにも指定できます。

V.FileSaveAs('C:\SEMPERFI.DOC', Password := 'Sam');

この結果，SEMPERFI.DOC が Word 形式で保存され，パスワード「Sam」が割り当てられます。したがって，次にこの文書を開くときは，このパスワードを指定しなければなりません。

上のコードはパラメータの名前を使った例です。「Password」パラメータを名前で指定しています。Password パラメータは通常は 4 番目にこの関数に渡されますが，名前で指定すれば 2 番目に渡すことができます。これは次のコード行と同じ結果になります。

V.FileSaveAs(Password := 'Sam', Name := 'C:\SEMPERFI.DOC');

このコードは，パラメータ名を使うとパラメータをスキップできるほかに，パラメータを使う順序を変更できることを示しています。

Word では，パラメータ名のほかにパラメータの位置で指定することもできます。

V.FileSaveAs('C:\SEMPERFI.DOC',,,'Sammy');

このコードでは，SEMPERFI.DOC とパスワード「Sammy」を指定しています。「Sammy」は 4 番目の位置にあるので，これをパスワードにすることを Word は認識します。この場合，2 番目と 3 番目のパラメータは空白なので，それぞれデフォルト値が使われます。


Variant arrays
Variant arrays1069008

Section topics	参照

Delphi では，バリアント型の配列を作成できます。バリアント型の配列は，OLE オートメーションで使う SafeArray の Delphi バージョンです。つまり，バリアント型配列は Delphi の安全な配列の実装です。

バリアント型配列と安全な配列はメモリや CPU サイクルをかなり消費するので，OLE オートメーションコードの場合と標準的な配列を使うよりも，明らかに利点がある場合を除いては使いません。たとえば，データベースを扱う部分の一部ではバリアント型配列を利用しています。

これらには入っている次元の数と各次元の範囲を示す情報があるので，OLE コードは SafeArray として参照します。Windows ファイル OLEAUTO32.DLL には，このような配列を処理するすべての SafeArrayX 呼び出しが入っています。

Delphi では SafeArrayX 呼び出しをいくつかの関数にカプセル化しています。このような関数でもっとも重要なのは，VarArrayCreate と VarArrayOf です。これらはバリアント型配列の作成に使われます。

VarArrayCreate は次のように宣言されています。

function VarArrayCreate(const Bounds: array of Integer; VarType: Integer): Variant;

Bounds パラメータは配列の次元を定義し，VarType パラメータは配列に格納する変数の型を定義します。1 次元のバリアント型配列は次のように割り当てられます。

MyVariant := VarArrayCreate([0, 5], varVariant);

この配列には 6 個の要素があり，それぞれがバリアント型です。この配列の 1 つまたは複数の要素にバリアント型配列を代入できます。配列をネストにするにはこの方法を使います。

配列で使う要素の型がわかっている場合，VarType パラメータをその型に設定します。たとえば，整数を処理するつもりであれば，次のようにコードを作成します。

MyVariant := VarArrayCreate([0, 5], varInteger);

2 番目のパラメータ (Integer で宣言されている) では varString を使えないので，varOleStr をかわりに使う必要があります。ほかの型の場合にはもっと少なくて済みますが，バリアント型の配列の場合，各配列要素に 16 バイト必要です。

バリアント型の配列のサイズは，VarArrayRedim 関数を使って変更できます。

procedure VarArrayRedim(var A: Variant; HighBound: Integer);

サイズ変更する変数を最初のパラメータで渡し，配列内の要素の数は 2 番目のパラメータに入れます。

2 次元配列は次のように宣言します。

MyVariant := VarArrayCreate([0, 5, 0, 5], varVariant);

この配列は 2 次元であり，それぞれ 6 個の要素があります。この配列のメンバーにアクセスするには，次のようなコードを作成します。

procedure TForm1.GridClick(Sender: TObject);

var

  MyVariant: Variant;

begin

  MyVariant := VarArrayCreate([0, 5, 0, 5], varVariant);

  MyVariant[0, 1] := 42;

  Form1.Caption := MyVariant[0, 1];

end;

この配列はバリアント型の配列であり整数の配列ではないので，型を変換します。

1 次元のバリアント型配列を簡単に構築するには，VarArrayOf ルーチンを使います。

function VarArrayOf(const Values: array of Variant): Variant;

この関数は，内部的に VarArrayCreate を呼び出して，最初のパラメータで Variant 配列を，2 番目のパラメータで varVariant を渡します。次に VarArrayOf を呼び出す一般的なコードを示します。

V := VarArrayOf([1, 2, 3, 'Total', 5]);

次のコードは VarArrayOf 関数の使い方を示しています。

procedure TForm1.ShowInfo(V: Variant);

begin

  Caption := V[3];

end;

procedure TForm1.Button1Click(Sender: TObject);

var

  V: Variant;

begin

  V := VarArrayOf([1, 2, 3, 'Four', 5]);

  ShowInfo(V);

end;

このコードは Form1 のキャプションに「Four」を表示します。

ShowInfo 関数は，OLE 関数またはほかのルーチンによって渡されたバリアント型配列を処理する方法を示します。バリアント型に配列としてアクセスするのに特別な処理は不要です。varInteger の VType でバリアント型をこの関数に渡す場合，バリアント型を配列として処理しようとすると例外が生成されます。つまり，バリアント型に VarArray の VType が指定されていないと，ShowInfo 呼び出しは失敗します。VarType 関数を使うと，バリアント型の VType の現在の設定をチェックできます。または VarIsArray を呼び出せば，論理値が返されます。

関数 VarArrayHighBound，VarArrayLowBound，VarArrayDimCount を使うと，配列の次元数と，各次元の範囲を調べることができます。次の関数は MessageBox を呼び出し，バリアント型配列の次元数と，各次元の上限と下限の値を表示します。

procedure TForm1.ShowInfo(V: Variant);

var

  Count, HighBound, LowBound, i: Integer;

  S: string;

begin

  Count := VarArrayDimCount(V);

  S := #13 + 'DimCount: ' + IntToStr(Count) + #13;

  for i := 1 to Count do

  begin

    HighBound := VarArrayHighBound(V, i);

    LowBound := VarArrayLowBound(V, i);

    S := S + 'HighBound: ' + IntToStr(HighBound) + #13;

    S := S + 'LowBound: ' + IntToStr(LowBound) + #13;

  end;

  ShowMessage(S);

end;

このルーチンは，最初に配列の次元数を取り出します。各次元でルーチンを繰り返して，上限値と下限値を調べます。次の呼び出しを使って配列を作成するとします。

MyVariant := VarArrayCreate([0, 5, 1, 3], varVariant);

ShowInfo 関数は MyVariant が渡されると，次のように出力します。

DimCount: 2

HighBound = 5

LowBound  = 0

HighBound = 3

LowBound = 1

VarIsArray が False を返すような値をバリアント型として渡すと，ShowInfo は例外を生成します。

バリアント型配列を処理するとかなりのオーバーヘッドになります。配列を迅速に処理するには，VarArrayLock と VarArrayUnlock という 2 つの関数を使います。前者は配列に格納されたデータへのポインタを返します。特に，バリアント型配列を指定すると標準の Object Pascal 配列が返されます。これが正しく実行されるには，Integer，Bool，string，Byte，Float などの標準の型を配列で明示的に宣言する必要があります。バリアント型配列で使う型と Object Pascal 配列で使う型がすべてのメンバーで一致していなければなりません。

次に，VarArrayLock と VarArrayUnlock の使い方の例を示します。

const

  HighVal = 12;

function GetArray: Variant;

var

  V: Variant;

  i, j: Integer;

begin

  V := VarArrayCreate([0, HighVal, 0, HighVal], varInteger);

  for i := 0 to HighVal do

    for j := 0 to HighVal do

      V[j, i] := i * j;

  Result := V;

end;

procedure TForm1.LockedArray1Click(Sender: TObject);

type

  TData = array[0..HighVal, 0..HighVal] of Integer;

var

  i, j: Integer;

  V: Variant;

  Data: ^TData;

begin

  V := GetArray;

  Data := VarArrayLock(V);

  for i := 0 to HighVal do

    for j := 0 to HighVal do

      Grid.Cells[i, j] := IntToStr(Data^[i, j]);

  VarArrayUnLock(V);

end;

このコードは最初に配列をロックしてから，標準配列へのポインタとして配列にアクセスします。処理が完了すると，配列を解放します。配列のデータの処理が終わったら，必ず VarArrayUnlock を呼び出してください。

 Data := VarArrayLock(V);

  for i := 0 to HighVal do

    for j := 0 to HighVal do

バリアント型を使う最大の利点は，OLE サーバーとの間でバイナリデータをやりとりできることです。バリアント配列を使うことで，WAV や AVI などのバイナリファイルをプログラムと OLE サーバーとの間でやりとりできます。このようなとき，VarArrayLock や VarArrayUnlock を使います。この場合，VarArrayCreate の 第 2 パラメータを VarByte と指定して作成した配列を使います。そして，データ構造をやりとりする前に配列をロックすることでバイト型の配列として使うことができ，内容を直接参照できるようになります。このような配列は境界を越えてマーシャリングされる際にも変換されません。

バリアント型配列は，特別な場合にだけ使用するものであることを忘れないでください。バリアント型配列は，OLE オートメーションオブジェクトを呼び出すときなどは大変便利なツールです。しかし，標準的な Object Pascal 配列よりも処理速度が遅く容量もかさばるので，必要な場合だけ使うようにしてください


See also1069009


Creating an MDI application
Creating an MDI application1075001

Section topics	参照

この章では，簡単な MDI (マルチドキュメントインターフェース) テキストエディタアプリケーションを構築するステップについて説明します。MDI アプリケーションを使うと，ユーザーはアプリケーションのメインウィンドウ内で子ウィンドウを開いて，作成した文書で通常のワープロ操作ができます。MDI アプリケーションのユーザーは，メインウィンドウから新規ファイルでも既存のファイルでも開いて，文書ウィンドウから印刷したり，Windows の標準ダイアログボックスを使ってそのファイルを操作できます。

Delphi のフォームには Windows の MDI 標準が完全にカプセル化されているので，わずかなコーディングで本格的な MDI アプリケーションを仕上げて実行できます。

完成したテキストエディタアプリケーションを表示するには，Delphi  をインストールしたデフォルトディレクトリの DEMOS\DOC\TEXTEDIT ディレクトリにあるプロジェクトファイル TEXTEDIT.DPR を開きます。図に完成したアプリケーションで新しいウィンドウを開いたときの状態を示します。1075002

メモ	メニューの［ファイル(F)｜新規作成(N)］で［新規作成］ダイアログを開き，［プロジェクト］ページの MDI アプリケーションテンプレートを使って作成することができます。


About MDI applications
About MDI applications1075003

Section topics	参照

MDI (マルチドキュメントインターフェース) は，単一のフレームウィンドウ内で複数のファイルつまり文書を同時に開いて表示するアプリケーションのための標準インターフェースです。たとえば，ワープロアプリケーションで複数の文書を同時に開いて表示し，開いている文書間でユーザーがすばやく切り替えできるようにする場合などに MDI を使います。

MDI アプリケーションは，共通の作業領域を共有する複数の文書を表示して互いにデータを交換するのに便利です。この共通の作業領域を「フレームウィンドウ」といいます。Delphi の MDI アプリケーションでは，フレームウィンドウが常にアプリケーションのメインフォームになります。

フレームウィンドウ内では，「子ウィンドウ」というほかのウィンドウに文書が表示されます。これらの文書のファイルの種類は，すべて同じであっても，文書ごとに異なっていてもかまいません。MDI では，子ウィンドウでの操作を制限することはなく，フレーム内の子ウィンドウの管理と配置だけを行います。

この節では，MDI アプリケーションを作成する以下の基本的なステップについて説明します。

MDI フレームフォームの作成

MDI 子フォームの作成

MDI アプリケーションメニューについて

マージするメニューのグループ化

実行時の子ウィンドウの作成

子ウィンドウの操作


Creating the MDI frame form
Creating the MDI frame form1075004

Section topics	参照

MDI アプリケーションでは，フレームウィンドウはアプリケーションの文書のための作業領域になります。アプリケーションの文書は，1 つまたは複数の子ウィンドウ内に開きます。MDI アプリケーションを構築する最初のステップとして，フレームフォームを作成します。

Delphi のすべてのフォームには，そのフォームがフレームフォームか子フォームか (または MDI 以外のアプリケーションのフォームか) を決める FormStyle プロパティがあります。アプリケーション 1 つにつき設定できる MDI フレームフォームは 1 つだけです。このフォームはアプリケーションのメインフォームにしなければなりません。

MDI フレームフォームを作成する手順は次のとおりです。

1.	このアプリケーションのメインフォームとなるフォームを選択します。

2.	メインフォームの FormStyle プロパティに fsMDIForm を設定します。

注意	fsMDIForm は，どのフォームの FormStyle プロパティにでも設定できます。しかし，アプリケーションのメインフォームでないフォームの FormStyle プロパティに対して fsMDIForm を設定すると，アプリケーションは正しくコンパイルされません。アプリケーションのメインフォームを変更するには，［プロジェクト(P)｜オプション(O)］を選択して［フォーム］ページを選びます。


Creating the MDI child form
Creating the MDI child form1075005

Section topics	参照

子フォームは，ユーザーが実行時に開くことができる子ウィンドウの種類ごとに，テンプレートとして設計時に作成します。これで，ユーザーは子ウィンドウの種類ごとに複数のインスタンスを開くことができます。MDI アプリケーションで子フォームのインスタンスが作成されるとすぐに，そのインスタンスがフレームフォームの作業領域に表示されます。

たとえば，このサンプルでは，ユーザーが［File｜New］を選択するたびにテキストエディタ (子) フォームのインスタンスが作成されます。子ウィンドウの各インスタンスの初期状態は，同じフォームファイルから読み出されます。

MDI 子フォームを作成する手順は次のとおりです。

1.	新しい空白フォームをプロジェクトに追加します。

2.	新しいフォームの FormStyle プロパティに fsMDIChild を設定します。

デフォルトでは，Delphi のフォームにはアプリケーション起動時に作成されるインスタンスが含まれます。このインスタンスは，「子ウィンドウの作成」で変更します。

メモ	通常は，［プロジェクトオプション］ダイアログボックスの［フォーム］ページにある自動作成フォームリストから MDI の子フォームを削除する必要があります。これは，MDI アプリケーションが実行時に 1 つの子から複数のインスタンスを作成してしまうためです。データベースのようなアプリケーションで，複数の種類の子フォームごとに 1 つのインスタンスだけしか使用しない場合には，実行時に子フォームをそれぞれ作成する必要はなく，自動作成リストからフォームを削除する必要もありません。自動作成フォームリストについての詳細は，「自動作成するフォームの指定」を参照してください。


About MDI application menus
About MDI application menus1075006

Section topics	参照

MDI アプリケーションのフォームのメニューを作成するには，単一フォームのアプリケーションの場合と同じように，メニューコンポーネントとメニューデザイナを使います。ただし，MDI アプリケーションの場合は，フレームフォームのメニュー項目と子フォームのメニュー項目を共有のメニューバーでどのように相互作用させるかという問題にも対処しなければなりません。

デフォルトでは，子ウィンドウにフォーカスがあれば，フレームウィンドウのメニューバーはその子ウィンドウのメニューバーで置き換えられます。もっと簡潔に対処する方法として，フォーカスがある子ウィンドウ用のメニュー項目を，どのウィンドウにも適用できるフレームウィンドウのメニュー項目と結合する方法があります。これをメニューの「マージ」といいます。

フレームフォームのメニュー項目は，子ウィンドウを操作する項目か，子ウィンドウが開いていないときに機能する項目でなければなりません。フレームフォームのもっとも一般的なメニュー項目が，子ウィンドウを開くための［File］メニューと，子ウィンドウを操作するための［Window］メニューです。［File］と［Window］メニュー項目は，特定の子ウィンドウの独自の機能ではなく，フレームに関する機能をコントロールするため，フレームフォーム内にあります。

ユーザーが子ウィンドウを開くと，アプリケーションが子フォームのメニュー項目をメインメニューのメニューバーにマージします。

マージされたメニュー項目の順序は，各メニューのメニュー項目ごとに，GroupIndex プロパティに値を設定して制御します。実際には，GroupIndex プロパティを使うと，子フォームのメニュー項目をメインメニューに挿入せずに，メインメニューの項目を子フォームのメニュー項目で「置き換える」ことになります。たとえば，フレームフォームと子フォームの両方の［File］メニュー項目に対して GroupIndex に 0 の値を設定します。すると，ユーザーが子ウィンドウを開いたときに，フレームフォームの［File］が完全に子フォームの［File］で置き換えられます (値 0 に設定すると［File］メニューは常に左端に表示されます)。


Creating the frame-form menu
Creating the frame-form menu1075007

Section topics	参照

フレームフォームのメニューバーは，MDI アプリケーションのメインメニューとして機能します。

フレームフォームのメニューを作成する手順は次のとおりです。

1.	メインメニューコンポーネントをフレームフォームに追加します。

2.	メニューデザイナを使って項目をメニューに追加します。


Creating a child-form menu
Creating a child-form menu1075008

Section topics	参照

MDI 子フォームのメニューには，子ウィンドウで必要なすべての専用機能を持たせます。たとえば，子ウィンドウにテキストエディタがある場合，ユーザーはテキストを操作するためのメニュー項目がその子ウィンドウで必要になります。子ウィンドウにグラフィックイメージがある場合，メニュー項目でサイズの変更や色の指定などができるようにします。

MDI 子フォームのメニューを作成する手順は次のとおりです。

1.	メインメニューコンポーネントを子フォームに追加します。

2.	メニューデザイナを使って項目をメニューに追加します。


Grouping menus for merging
Grouping menus for merging1075009

Section topics	参照

MDI アプリケーションには，どの子ウィンドウにフォーカスがあるかによってメニューを変更できるという特徴があります。MDI アプリケーションで子ウィンドウが開いていない場合，フレームフォームのメニューがメインメニューになります。子ウィンドウのメニュー項目をメインメニューに追加することも，既存の項目を子ウィンドウのメニュー項目で置き換えることもできます。これをメニューの「マージ」といいます。

Delphi の MDI アプリケーションでは，メニューのマージは自動的に処理されます。ただし，［Edit］メニューの追加や［File］メニュー全体の置き換えなどのように，項目からなるメニュー全体だけをマージできることに注意してください。たとえば，［File］メニュー内の個々の項目はマージできません。

メニューのマージは，メニューをグループ化し，グループごとにインデックス番号を割り当てて制御します。MDI アプリケーションでは，同じインデックス番号のすべてのメニューは同じグループに属しているとみなされます。したがって，挿入や置き換えを必ずまとめて行う必要がある複数のメニューには，同じインデックス番号を割り当てなければなりません。

メニュー項目のグループを作成する手順は次のとおりです。

1.	グループ化するすべてのメニュー項目を選択します。

2.	GroupIndex プロパティに整数値を設定します。以下の規則に注意してください。

メニューの GroupIndex 値は，そのメニューの左側に表示されるメニューの GroupIndex 値以上でなければならない。グループ内のメニュー項目では，設計時の左から右の順序が維持される

子フォームのメニューのグループは，GroupIndex 値が同じであるフレームフォームのメニューのグループのかわりに使われる

マージされたメインメニューには，GroupIndex 値の昇順にメニュー項目のグループが表示される。GroupIndex 値が最小のグループが左端に表示される

3.	メニューのグループごとにこの手順を繰り返します。


Handling replaced menu commands
Handling replaced menu commands1075010

Section topics	参照

マージしたメニューでほかのメニューを置き換える場合，いくつかの類似した項目や同じ項目が置き換えられることがよくあります。たとえば，さまざまな子ウィンドウの専用項目を完全に［File］メニューに追加する場合などですが，その場合でも［File｜New］や［File｜Exit］などの標準項目は残します。このような項目ごとにイベントハンドラのコードを複製するかわりに，共通のコードを一度記述して，置き換えるメニュー項目から呼び出すことができます。

マージしたメニュー間でイベントハンドラを共有する手順は次のとおりです。

1.	イベントハンドラをフレームフォームのメニュー項目に結び付けます。
メニュー項目に応じた処理は，どのような処理でもこのイベントハンドラが実行します。

2.	イベントハンドラを子フォームの対応するメニュー項目に結び付けます。

3.	子フォームのイベントハンドラからフレームフォームのイベントハンドラを呼び出します。


Creating child windows
Creating child windows1075011

Section topics	参照

MDI アプリケーションのメインフォームと子フォームを作成し，そのメニューを設定したら，実行時に子ウィンドウを作成する方法と場合を特定します。

ほとんどの MDI アプリケーションでは，子ウィンドウの自動作成は必要ありません。そのかわりに，新規文書を開いたり作成したりする場合など，必要なときに MDI アプリケーションで子ウィンドウを作成するようにします。

アプリケーションによる子ウィンドウの作成をユーザーが完全に制御できるようにするには，以下の 2 つが必要です。

1.	自動作成リストからの子ウィンドウの削除

2.	実行時の子ウィンドウの作成


Removing the child from auto-creation
Removing the child from auto-creation1075012

Section topics	参照

ほとんどの場合，MDI アプリケーションで子ウィンドウのインスタンスを自動的に作成する必要はありません。MDI アプリケーションでは，ユーザーが［File｜New］を選択した場合など，必要になときだけ子ウィンドウが追加されるようにするのが普通です。

通常は，プロジェクトの自動作成リストから子ウィンドウのフォームを削除します。

自動作成リストからフォームを削除する手順は次のとおりです。

1.	［プロジェクト(P)｜オプション(O)］を選択して自動作成フォームリストにアクセスします。

2.	［自動作成の対象(A)］リストで，自動作成の対象にしないフォームを選択します。

3.	［>］ボタンをクリックしてフォームを［選択可能なフォーム(F)］リストに移動します。

4.	［OK］を選択してダイアログボックスを閉じます。


Creating child windows at runtime
Creating child windows at runtime1075013

Section topics	参照

ほとんどの MDI アプリケーションで，ユーザーは実行時に新しい子ウィンドウを開くことができます。新しいウィンドウを開くのにもっともよく使う手段は，［File｜New］などのメニュー項目です。この場合，［File｜New］のクリックに対するイベントハンドラに子ウィンドウを作成しておきます。アプリケーションでは，ほかのイベントに応じて子ウィンドウを作成する場合も，ほかのコード内に子ウィンドウを作成する場合もあります。

実行時に新しい子ウィンドウを作成する手順は次のとおりです。

1.	コード内で，子ウィンドウを作成する場所を決めます。
通常は，メニュー項目のイベントハンドラで作成します。必要であれば，目的のメニュー項目のクリックに対して空のイベントハンドラを生成します。

2.	インスタンスが必要な子ウィンドウのフォームの Create メソッドを呼び出し，フレームウィンドウを Owner パラメータとして Create メソッドに渡します。

次の例では，フレームフォームのハンドラは子フォームの型 (TEditForm) の Create メソッドを呼び出します。子フォームのハンドラはフレームフォームのハンドラを呼び出すだけです。

procedure TFrameForm.New1Click(Sender: TObject);

begin

  TEditForm.Create(Self);	{新しい子ウィンドウを作成する}

end;

procedure TEditForm.New1Click(Sender: TObject);

begin

  FrameForm.New1Click(Sender);	{フレームフォームのハンドラを呼び出す}

end;

既存のファイルを開くのはもう少し複雑になります。既存のファイルを開く方法についての詳細は，「開くファイルの選択」を参照してください。


Referencing identifiers in other units
Referencing identifiers in other units1075014

Section topics	参照

この時点でアプリケーションをコンパイルしようすると，未知のオブジェクトが見つかったときに，「未定義の識別子」というエラーメッセージが生成されます。参照されているシンボルがすでにコンパイルされていると，コンパイラはコンパイル済みのユニットを使うように促します。しかし，コンパイラが ユニットをまだコンパイルしていないと，このユニットを使うように促すことができません。このユニットは手動で参照する必要があります。

ほかのフォームのユニットで宣言されている要素を参照する場合は，そのユニットを，参照元フォームのユニットの uses 節に指定しなければなりません。

フォームのユニットからほかのユニットを参照する手順は次のとおりです。

1.	ほかのユニットを参照する必要があるフォームを選択します。

2.	［ファイル(F)｜ユニットを使う(U)］を選択します。
［ユニットを使う］ダイアログボックスが開きます。

3.	使うユニットを選択します。

4.	［OK］を選択してダイアログボックスを閉じます。
選択したユニットが現在のユニットの uses 節に追加されます。


Manipulating child windows
Manipulating child windows1075015

Section topics	参照

［File｜New］メニューコマンドに応答してアプリケーションで新しい子ウィンドウを作成できるようになったら，開いている子ウィンドウを操作するコードを記述できます。具体的には，子ウィンドウを閉じるメニュー項目や子ウィンドウの配置を変えるメニュー項目にイベントハンドラを結び付けたり，開いている子ウィンドウのリストを［Window］メニューに追加したりできます。さらに，子ウィンドウごとにキャプションをカスタマイズして，各子ウィンドウ内の文書の名前がわかるようにもできます。


Closing child windows
Closing child windows1075016

Section topics	参照

子ウィンドウを開くことができるアプリケーションでは，子ウィンドウを閉じることもできなければなりません。Delphi によるウィンドウのカプセル化では，ウィンドウのフレームにあるクローズボタンをクリックするか，ウィンドウのコントロールメニューボックスをダブルクリックするか，〔Ctrl〕+〔F4〕キーを押すと，Close というメソッドが呼び出されてウィンドウが閉じます。アプリケーションでは，［File｜Close］メニューコマンドの選択など，ほかの方法で Close メソッドを呼び出すことによって，アクティブな子ウィンドウを閉じることもできます。

子ウィンドウを閉じるには次のようにします。

子ウィンドウの Close メソッドを呼び出します。

MDI 子ウィンドウを閉じるときのデフォルトの動作で，子ウィンドウが閉じずに「アイコン化」されます。これは，OnClose イベントの Action というパラメータによって制御されます。デフォルトでは，Action の値は caMinimize です。Action に caFree を設定すると，アプリケーションでウィンドウが消去され，閉じるときにリソースが解放されます。

子ウィンドウを閉じるときの動作を変更する手順は次のとおりです。

1.	ハンドラを子フォームの OnClose イベントに結び付けます。

2.	Action パラメータの値を変更します。


Arranging open child windows
Arranging open child windows1075017

Section topics	参照

MDI アプリケーションには，フレームウィンドウで開いている文書の配置をユーザーが簡単に変えられるようにするために，［Tile］，［Cascade］，［Arrange Icon］の各コマンドが含まれた［Window］メニューが常に必要です。サンプルアプリケーションには［Window］メニューをすでに作成してあります。数行のコードを記述するだけで，［Tile］，［Cascade］，［Arrange Icon］の各コマンドが使えるように なります。Delphi のフォームコンポーネントには，ウィンドウを並べて表示する操作，ウィンドウを重ねて表示する操作，アイコンを整列する操作を処理するメソッドが組み込まれています。ユーザーは，このようなメソッドを，対応するメニュー項目に応じて呼び出すだけです。

MDI 子ウィンドウを並べて表示するか，重ねて表示するか，アイコンにして整列するには次のようにします。

フレームフォームの Tile メソッド，Cascade メソッド，ArrangeIcons メソッドをそれぞれ呼び出します。


Providing a list of open documents
Providing a list of open documents1075018

Section topics	参照

MDI フォームのメニューバーに表示されているどのメニュー項目にでも，開いている文書のリストを追加できます。ただし，追加できるリストは 1 つのメニューバーについて 1 つだけです。開いている文書のリストはメニューの最後の項目の下に表示されます。

開いている文書のリストをメニューに含める手順は次のとおりです。

1.	フレームフォームを選択し，オブジェクトインスペクタの［プロパティ］ページを選びます。

2.	WindowMenu プロパティの隣のドロップダウンリストで，開いている文書のリストを表示するメニュー項目の名前を選択します (キャプションではありません)。
この名前はサブメニューの項目の名前ではなく，必ずメニューバーの項目の名前にしなければなりません。ネストしたメニューでは文書リストが使えないからです。


Naming the child windows
Naming the child windows1075019

Section topics	参照

マルチドキュメントの設定では，すべての子ウィンドウの名前を別々にすると便利です。ほとんどの場合，名前を別々にすることは，文書の名前のような情報をキャプションに表示することと同じです。

パス名は長くなることがあるので，ファイル名の部分だけをキャプションに表示しますが，パス名全体はフォームレベルの変数に格納します。たとえば，EditForm の private 部に追加した次の宣言では，PathName という文字列型フィールドを定義します。

PathName: string;

PathName は各子ウィンドウ内のテキストファイルの名前を保持します。ファイルを開いたり保存したりするときや，バックアップファイルを作成するときに PathName を使います。

注意	private 部では，すべてのフィールド宣言をメソッド宣言の前に指定しなければなりません。したがって，EditForm の型宣言では予約語 private の直後に PathName 宣言を指定しなければなりません。

PathName の初期値を設定する必要もあります。アプリケーションで最初に子フォームを作成するときに，この設定ができます。この初期値は後で参照しなければならないので，MDI ユニットの interface 部に定数として宣言してもかまいません。

const

  DefaultFileName = 'Untitled';

ここで初期値として DefaultFileName を割り当て，後でテストできます。

procedure TEditForm.FormCreate(Sender: TObject);

begin

  PathName := DefaultFileName;

end;

後でファイルをエディタに読み込むときに，実パス名を PathName に割り当て，すでに保存してあるファイルがエディタにあることがわかるようにします。


Putting documents in child forms
Putting documents in child forms1075020

Section topics	参照

フレームフォームと子フォームを作成し，両方のフォームのメニューの内容を指定し，これらのフォームの実行時の動作を処理し，さらに子ウィンドウを操作するための基本的なコマンドや機能を使えるようになると，この時点で子ウィンドウに文書を挿入する準備ができます。

MDI アプリケーションの機能を確立するのは，子ウィンドウの内容 (文書) です。MDI アプリケーションはそれぞれ異なるため，文書を実現するためのすべての作業を一般化することは実際には不可能です。この例では，主にテキスト文書の編集について説明しています。それは，この例のアプリケーションが簡単な文書アプリケーションであるからというだけでなく，テキストの編集作業がさまざまなアプリケーションで共通していることが比較的多いからです。たとえば，クリップボードを使ったテキストの切り貼りは，さまざまなコントロールやアプリケーションに適用されます。


Filling a form with a document
Filling a form with a document1075021

Section topics	参照

MDI 子ウィンドウの内容に対する制約はありません。Delphi のフォームは，どんなに複雑でも MDI 子ウィンドウにすることができます。ただし，もっとも一般的な種類の MDI 子ウィンドウは，文書に対応したコンポーネントが 1 つだけ入った MDI 子ウィンドウです。文書にはテキストファイル，グラフィックイメージ，表計算データなどがあります。

子ウィンドウのフォームに文書を入れる手順は次のとおりです。

1.	子フォームを選択します。

2.	子フォームに文書コンポーネントを入れます。

3.	文書コンポーネントの Align プロパティに alClient を設定します。

4.	文書コンポーネントで目に見える境界を使用不可にします。たとえば，BorderStyle プロパティに bsNone を設定します。

文書コンポーネントのほかのプロパティも設定しなければならない場合があります。このような設定が必要なのは，文書を子フォームいっぱいに表示し，コンポーネントとウィンドウフレームとの間の目に見える区切りを除去する場合です。

たとえば，書式付きテキスト (RichEdit) またはメモ (Memo) コンポーネントを使って，テキストエディタを文書コンポーネントとして追加できます。書式付きテキストコンポーネントを使うと性能がよくなり，さらにテキストの形式を変更できるようになります。通常は，表 26.1 に示すような値にプロパティを設定します。

プロパティ	値
Align	alClient
BorderStyle	bsNone
ScrollBars	ssVertical
Name	Editor
Lines	<空>
.


Exiting gracefully
Exiting gracefully1075022

Section topics	参照

ユーザーがデータを変更してファイルに保存できるアプリケーションでは，作業結果を保護する対策を講じます。たとえば，ユーザーが既存のファイルを保存するたびにバックアップファイルを作成します。変更を追跡して，保存していない変更があればアプリケーションを終了する前に保存するようにユーザーに促すことも重要です。

アプリケーションの終了時には，それぞれの子ウィンドウを閉じます。したがって，個々のウィンドウを閉じる際の処理により，変更を保存していない子ウィンドウが 1 つでもあるアプリケーションをユーザーが終了しようとした場合にも対処できます。

フォームを閉じる前に，Close メソッドが OnCloseQuery イベントを生成します。OnCloseQuery イベントには，CanClose という論理変数パラメータがあります。デフォルトでは CanClose は True で，OnClose イベントの生成などでフォームが閉じることを示しています。

フォームが閉じないようにする手順は次のとおりです。

1.	フォームの OnCloseQuery イベントにハンドラを結び付けます。

2.	CanClose パラメータに False を設定します。通常このパラメータは，保存していない変更が文書にあるかどうかを条件として変化します。

たとえば，次の例では，エディタコンポーネントの Modified プロパティで，保存していない変更があるかどうかを調べます。保存していない変更があれば，MessageDlg 関数を使ってメッセージダイアログボックスを生成します。Format 関数を使うと，メッセージボックスの確認文字列にファイル名を入れることができます。MessageDlg と Format についての詳細は，オンラインヘルプを参照してください。EditForm の OnCloseQuery イベントに次のハンドラを結び付けます。

procedure TEditForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);

const

  SWarningText = 'Save changes to %s?';

begin

  if Editor.Modified then	{保存していない変更がある場合だけ確認する}

  begin

    case MessageDlg(Format(SWarningText, [PathName]), mtConfirmation,

      [mbYes, mbNo, mbCancel], 0); of	{メッセージダイアログボックスを表示する}

      id_Yes: Save1Click(Self);	{［はい (Y)］の場合は保存する}

      id_Cancel: CanClose := False;
{［キャンセル］の場合はダイアログボックスを閉じるがフォームは閉じない}

    end;

  end;

end;

ユーザーがメッセージボックスで［いいえ(N)］を選択した場合の応答が必要でないことに注意してください。CanClose のデフォルトの値が True で，エディタの変更を保存せずに子ウィンドウが閉じることを示しているからです


See also1075023


Creating international applications
Creating international applications1066001

Section topics	参照

この章では，国際市場への配布を予定している Delphi アプリケーションの開発についての指針を解説します。計画的に進めることにより，国内市場のみならず国際市場におけるアプリケーション作成に必要な時間とコーディングの労力が削減できます。


Localization and internationalization
Localization and internationalization1066002

Section topics	参照

海外市場に配布できるアプリケーションを作成するには，2 つの主要なステップの実行が必要です。すなわち，国際化対応とローカライズ (地域または国別の対応) です。

Localization1066003

ローカライズとは，アプリケーションを特定のロケールで機能するように翻訳するプロセスです。ここでいうロケールとは，ターゲットとする国の言語や文化的慣習も含めたユーザー環境です。Windows では多様な環境をサポートしており，それぞれの国の言語で記述されています。

ユーザーインターフェースに表示される文字列の翻訳のほかに，ローカライズでは，ソート順序，日付，数字，通貨の表記形式など，その国に特有の要素の翻訳も行われます。

 Internationalization1066004

国際化対応は，プログラムが複数のロケールで動作できるようにするプロセスです。アプリケーションを国際化対応せずにローカルバージョンで配布することもできますが，これは効率的かつ経済的アプローチとはいえません。アプリケーションの国際化対応に費やす時間により，ローカルバージョンの開発に必要な労力は軽減されます。また，国際化対応アプリケーションのローカライズは，変更するコードが少ないので，製品にあまり影響しません。したがって，わずかのテストで，より安定したローカルバージョンのアプリケーションが作成できます。最後に，ローカライズしたアプリケーションは，改訂があっても複数のローカルバージョンに折り込む必要がないので，保守が簡単です。


Internationalizing Delphi applications
Internationalizing Delphi applications1066005

Section topics	参照

Delphi の国際化対応アプリケーションの作成は簡単ですが，主に考慮すべき点が 3 つあります。第 1 に，ローカライズに必要なすべてのリソースを分離することが必要です。第 2 に，ユーザーインターフェースをローカライズによる変更に適合するように設計する必要があります。そして最後に，国際的な文字セットの文字列をコードで処理できるようにする必要があります。


Isolating resources
Isolating resources1066006

Section topics	参照

アプリケーションのローカライズの中でもっとも明らかな作業は，ユーザーインターフェースに表示される文字列の翻訳です。コードのいたるところを変更しなくても翻訳できるアプリケーションを作成するには，ユーザーインターフェースの文字列を単一モジュールに分離する必要があります。Delphi では，自動的に .DFM ファイルが作成され，メニュー，ダイアログ，ビットマップ用のリソースがそこに格納されます。

このように明らかなユーザーインターフェース要素のほかに，ユーザーに送るエラーメッセージのような文字列もすべて分離しなければなりません。日付，時刻，数字，通貨形式はその国独自のものであるため，やはり分離します。文字列のリソースは .DFM ファイルに含まれませんが，キーワード resourcestring を使って定数を宣言して .DRC ファイルに分離できます。

リソース文字列定数についての詳細は『Object Pascal 言語ガイド』を参照してください。

すべてのリソース文字列定数は，1 つの独立したユニットに入れるとよいでしょう。.1 つのユニットにすべてのリソース文字列定数を入れると，アプリケーションのあちこちで複数の .DRC ファイルをローカライズするのではなく，1 つの .DRC ファイルをローカライズするだけで済みます。

.DFM と .DRC ファイルに分離したリソースをローカライズする方法については『開発者ガイド』を参照してください。


Designing the user interface
Designing the user interface1066007

Section topics	参照

アプリケーションを数ヶ国用に作成するには，翻訳の際に生じる変更に適合できるようにユーザーインターフェースを設計しておくことが重要です。

Text1066008

ユーザーインターフェースに含まれるテキストはすべて翻訳しなければなりません。多くの場合，元のテキストよりも翻訳したものの方が長くなります。テキストを表示するユーザーインターフェース要素については，テキスト文字列が長くなっても表示できるように設計してください。ダイアログ，メニュー，ステータスバー，その他のテキスト表示用のユーザーインターフェースは，長い文字列を簡単に表示できるように設計します。省略語は，表意文字を使う言語には存在しないので，使用を避けるようにします。

短い文字列でも，翻訳すると予想以上に長くなってしまいます。次の表は，英語の文字列の長さをどれくらい拡張すべきか概算したものです。

英語の文字列 (文字数)	予想される増加率
1～5	100%
6～12	80%
13～20	60%
21～30	40%
31～50	20%
50～	10%
Graphic images1066009

翻訳を必要としないイメージを使用できれば理想的ですが，これはグラフィックイメージにテキストを含むことができないことを意味します。テキストは常に翻訳が必要だからです。テキストをイメージに含む必要がある場合は，イメージの一部としてのテキストを持つのではなく，イメージの上で透過となる背景を持つラベルオブジェクトを使用するのがよいでしょう。

グラフィックイメージを作成するときに，もう 1 つ考慮すべき点があります。特定の文化に固有のイメージの使用は避けるようにします。たとえば，メールボックス (郵便ポスト) は，各国ごとにさまざまです。また，さまざまな宗教を持つ国々用のアプリケーションであれば，宗教的なシンボルの使用は適切ではありません。色でさえも，文化によってその象徴する意味がさまざまです。

Formats and sort order1066010

アプリケーションで使用する日付，時刻，数字，および通貨形式は，対象の国に合わせてローカライズする必要があります。Windows で定義される形式しか使わない場合は，それらは Windows レジストリから取り出して使用されるため，表示形式を翻訳する必要はありません。ただし，独自の形式文字列を指定している場合には，これをリソース定数として宣言し，ローカライズできるようにしてください。

文字列をソートする順序も国によってさまざまです。ヨーロッパ言語の多くには，国によってソート順序の異なる発音区別符号 (� や � などの符号) が含まれています。また，一部の国では 2 文字の組み合わせを 1 文字として扱ってソートします。たとえば，スペイン語の場合，ch は c と d の間の独自の文字 1 文字のようにソートされます。逆にドイツ語の eszett のように，1 文字でありながら 2 つの別々の文字のようにソートされるものもあります。

文字列のソートを行う Delphi コントロールでは，2 つの文字列を比較するソート関数を指定できるようになっています。アプリケーションをローカライズするときにソート関数もローカライズするようにしてください。

Keyboard mappings1066011

キーの組み合わせによるショートカットの割り当てには注意してください。英語キーボードの文字がすべてインターナショナル仕様のキーボードで使えるとは限りません。可能であれば，ショートカットには数字キーやファンクションキーを使用します。これらのキーは，実質的にすべてのキーボードにおいて使用できるからです。


Enabling application code
Enabling application code1066012

Section topics	参照

リソースを分離し，ユーザーインターフェースを翻訳リソースに適合するよう設計するほかに，アプリケーションのコードが，対象の国や地域で使用される文字列を処理できるようにする必要があります。

Character sets1066013

米国と大部分のヨーロッパの国々の Windows オペレーティングシステムでは，ANSI 文字セットを使用しています。しかし，アジアバージョンの Windows では別の文字セットを使用しなければなりません。たとえば，日本語バージョンでは Shift-JIS 文字セットを使用しています。Shift-JIS 文字セットは日本語を 1 バイトまたは 2 バイトの文字コードとして表します。Delphi はローカルな Windows 文字セットを使用して，画面に文字列を表示し，ユーザーが入力した文字列を読み込みます。

Delphi アプリケーションでフォントを指定するときは，コードに合ったフォントの文字セットを使用するようにしてください (通常は，Windows ローカルバージョンが使用する文字セット)。TFont オブジェクトには CharSet プロパティがあります。このプロパティを使って，使用するフォントの文字セットを制御できます。ユーザーがフォントを選択できるようする場合は，フォントの文字セットを指定できるフォント設定用のコモンダイアログボックスを使用するとよいでしょう。

OEM and ANSI character sets1066014

ヨーロッパ市場を対象とするアプリケーションを開発する場合，Windows 文字セット (ANSI) とユーザーのシステムのコードページで指定される文字セット (OEM 文字セットという) の変換を必要とすることがあります。たとえば，ボーランドデータベースエンジン (BDE) は，API 関数呼び出しの際にはOEM 文字セットの使用を想定しています。Delphi データベースコンポーネントを使用している場合は，OEM と ANSI 文字セットの変換を心配する必要はありません。これらのコンポーネントはすべての必要な変換を自動的に処理します。ただし，BDE API を直接呼び出すときは，Delphi が使用する ANSI 文字と BDE が使用する OEM 文字の変換を必ず行ってください。

Double byte characters sets1066015

東アジア地域で使用される表意文字 (漢字) は，1 バイト (8 ビット) の Char 型の間では単純な 1 対 1 のマッピングが行えません。東アジア諸国の言語は多数の文字を使用するため，1 バイトの Char ではすべての文字を表現できません。こうした文字は，1 バイトと 2 バイトの文字コードを組み合わせて表現されます。2 バイトの文字コードの最初の 1 バイト (第 1 バイト) には予約された一定範囲のコードが割り当てられていますが，予約範囲は個々の文字セットにより異なります。2 番目のバイト (第 2 バイト) の範囲は，独立した 1 バイト文字の文字コード，および第 1 バイトの予約範囲にまたがっています。したがって，文字列中の特定のバイトが 1 バイト文字なのか 2 バイト文字の一部なのかを知るには，文字列の先頭から順に，第 1 バイトの予約範囲内のバイトがあったら，次の 1 バイトと合わせて 2 バイト文字として解析しなければなりません。

東アジア地域用のコードを記述するときは，文字列を 1 バイトと 2 バイトの文字で解析できるような関数を使って，すべての文字列操作を処理するようにします。Delphi には，DBCS (double-byte character set) 文字列に対して使用できる次のような多数のランタイムライブラリ関数があります。

AnsiCompareFileName	AnsiStrIComp	ByteToCharIndex	ExtractFileName
AnsiExtractQuotedSet	AnsiStrLastComp	ByteToCharLen	ExtractFilePath
AnsiLastChar	AnsiStrLComp	ByteType	IsDelimiter
AnsiLowerCase	AnsiStrLIComp	ChangeFileText	IsPathDelimiter
AnsiLowerCaseFileName	AnsiStrLower	CharToByteIndex	LastDelimiter
AnsiPos	AnsiStrUpper	CharToByteLen	StrByteType
AnsiQuotedStr	AnsiUpperCase	ExtractFileDir
AnsiStrComp	AnsiUpperCaseFileName	ExtractFileExt

DBCS 文字列を扱うときは，ByteType または StrByteType 関数を使って，特定のバイトが 2 バイト文字の第 1 バイトかどうかを判断します。文字列のバイト数は文字数と一致するとは限らないことに注意してください。2 バイト文字を分断して文字列を切り捨てないようにしてください。文字のサイズが不明であるため，文字をパラメータとして関数や手続きに渡してはなりません。文字または文字列は，常にポインタを渡すようにします。文字列を処理するアルゴリズムは，文字列の先頭から順に解析するように記述します。この方が後ろから前へ文字列を調べるよりもコードが少なくて済みます。

Wide characters1066016

表意文字セットを扱うもう 1 つのアプローチは，すべての文字を Unicode のようなワイド文字に変換して符号化するという方法です。ワイド文字は 1 バイトではなく 2 バイトなので，文字セットは多種多様の文字を表記することができます。

1 バイト文字だけの文字列の処理では一般的であった仮定の多くは DBCS システムには適用できませんが，ワイド文字符号化方式を採用することで，それらが同じように適用できるという利点があります。文字列のバイト数と文字列の文字数の関係も一定したものになります。文字を分断してしまう心配もなく，文字の第 2 バイトを別の文字と間違える心配もありません。

Delphi は WideChar 型と WideString 型をサポートしています。ランタイムライブラリにはそれほど多くのワイド文字列関数はありませんが，大部分は簡単に独自に実装できます。Delphi では，標準の 1 バイト文字列 (または DBCS 文字列) と Unicode 文字列とを変換するためのいくつかのランタイム関数を提供しています。それらの関数は次のとおりです。

StringToWideChar

WideCharLenToString

WideCharLenToStrVar

WideCharToString

WideCharToStrVar

ワイド文字を扱う際の最大の問題点は，Windows 95 ではワイド文字の API 関数呼び出しをサポートしないことです。このため，Delphi コンポーネントは，すべての文字列の値を単一バイトまたは DBCS 文字列として表します。文字列プロパティの設定や値の読み出しごとにワイド文字システムと DBCS システム間の翻訳を行うと，膨大なコードの記述が新たに必要になり，アプリケーションの実行速度は低下します。しかし，文字と WideChar の 1 対 1 のマッピングの利用を必要とする一部の特殊な文字列処理アルゴリズムを使用する場合には，ワイド文字への翻訳が必要なこともあります。

Locale-specific features1066017

特定のロケールのアプリケーションに特別な機能を追加したい場合があります。特にアジアの言語環境では，ユーザーによる文字列へのキー入力を変換する入力メソッドエディタ (IME) の制御がアプリケーションに必要です。

Delphi コンポーネントは IME のプログラミングをサポートします。テキスト入力を直接扱うウィンドウコントロールのほとんどは，IMEName プロパティを持っています。このプロパティにより，コントロールが入力フォーカスを与えられたときに使用する特定の IME を指定することができます。また，IME のキーボード入力変換方法を指定する IMEMode プロパティもあります。TWinControl が複数のプロテクトメソッドを提供するので，定義したオブジェクトクラスからの IME コントロールが可能です。さらに，グローバル変数 Screen により，ユーザーのシステムで使用できる IME についての情報が提供されます。

グローバル変数 Screen は，ユーザーのシステムにインストールされているキーボードマッピングの情報も提供します。したがって，アプリケーションの実行環境に関する固有の情報が得られます。


Localizing Delphi applications
Localizing Delphi applications1066018

Section topics	参照

Delphi アプリケーションを国際化対応した後は，これを配布する特定の海外市場向けに，ローカライズバージョンを作成することができます。


Localizing resources
Localizing resources1066019

Section topics	参照

Delphi では，.DFM ファイルにユーザーインターフェース要素が分離されます。この .DFM ファイルを，Delphi に付属するコマンドラインユーティリティ Convert を使ってテキストファイルに変換することができます。引数として .DFM ファイル名だけを指定して Convert を呼び出すか，または別々の行に複数の .DFM ファイルのファイルリストを作成してから，@ 記号の後にこのファイル名を指定して Convert を呼び出します。

Convert を使ってリソースを翻訳したテキストファイルを作成した後，翻訳済みのテキストファイルを引数として指定し，もう一度 Convert を呼び出します。今度は，Convert は翻訳済みテキストファイルから新しい翻訳済み .DFM ファイルを作成します。ここで，Delphi 実行可能プログラム，DLL，またはパッケージを，ローカライズされた .DFM ファイルで再コンパイルすると，ローカライズされたユーザーインターフェースを持つアプリケーションバージョンが作成できます。

メモ	フォームを右クリックし，［テキストとして表示］を選択して IDE で，DFM ファイルを直接に翻訳することもできます。

文字列リソースに関しては，-gd コマンドラインスイッチを使ってコンパイルするか，または IDE からアプリケーションをコンパイルするときに［リンカ］ページの［詳細マップファイル］を指定する必要があります。これらのいずれかの方法でアプリケーションをコンパイルすると，.DRC ファイルが生成されます。このファイルには resourcestring キーワードを使って宣言したすべての文字列定数のテーブルが含まれます。文字列を .DRC ファイルに翻訳した後，Delphi に付属するコマンドラインユーティリティ BRCC32 を使って，.DRC ファイルをリソースファイル (.RES) にコンパイルします。そして，このローカライズされた .RES ファイルを実行可能プログラム，DLL，パッケージにリンクすると，アプリケーションのローカライズプロセスは終了します。


Creating resource modules
Creating resource modules1066020

Section topics	参照

アプリケーションの .DFM と .DRC ファイルに分離したリソースを，別々のリソースモジュールに分けると，リソースモジュールをアプリケーションの配布地域ごとに個々に作成することができます。

これは次の手順で行います。

1.	ローカライズするアプリケーションのターゲット市場用に 2 文字または 3 文字のローカルコードを取得します。このローカルコードは，グローバル関数 GetLocaleInfo を使って第 2 パラメータに LOCALE_SABBREVLANGNAME を指定すると取得できます。最初の 2 文字はターゲット言語を示し，最後の文字はその地域の国名を表します。

2.	［ファイル(F)｜新規作成(N)］を選択して，DLL を選び，新しいライブラリを作成します。

3.	新しい DLL には，ローカライズしたリソースファイルだけを入れます。たとえば，アプリケーション MyApp.exe で，インターフェースをローカライズして MyApp.dfm を作成し，文字列リソースをローカライズして MyApp.res を作成する場合，新しいライブラリに次のコードを追加します。

{$E MyApp.res}

{$E MyApp.dfm}

.DFM ファイルと .RES ファイルは完全なファイル名で記述します。*.DFM のような文字列でユニット名を指定してはいけません。

4.	ライブラリにアプリケーションの実行可能プログラム，DLL，またはパッケージと同じ名前を付けます。手順 1 で取得した 2 文字または 3 文字のロケールコードを拡張子として付けます。

ローカライズの必要なすべての実行可能プログラム，DLL，またはパッケージにリソースモジュールを作成してください。


Using resource modules
Using resource modules1066021

Section topics	参照

アプリケーションを構成する実行形式プログラム，DLL，およびパッケージには，コンパイルしたリソースがすべて含まれています。しかし，このリソースをローカライズバージョンに置き換えるのは，.EXE，.DLL，または .DPL ファイルと同じ名前のローカライズリソースモジュールをアプリケーションに追加するだけですみます。

Delphi のアプリケーションを起動すると，ローカルシステムのロケールがチェックされます。使用している .EXE，.DLL，または .DPL ファイルと同じ名前のリソースモジュールを検出すると，その拡張子が調べられます。リソースモジュールの拡張子がローカルシステムの言語または国と一致すると，アプリケーションは実行形式プログラム，DLL，およびパッケージ内のリソースのかわりにそのリソースモジュール内のリソースを使用します。言語と国の両方が一致するリソースモジュールがないと，アプリケーションは言語だけが一致するリソースモジュールを使用します。言語に一致するリソースモジュールもない場合には，実行形式プログラム，DLL，およびパッケージ内のリソースを使用します。

アプリケーションの内部ではグローバル関数 FindResourceHInstance を使って現在のリソースモジュールを処理します。

このように，適切なリソースモジュールを提供するだけで，1 つのアプリケーションを，実行するシステムのロケールに自動的に適合させることができます。


See also1066022

フォームファイル

リソースファイル

その他のファイル

メニューデザイナの使い方

オーナー描画コントロールの作成

グラフィックファイルの操作

形式文字列

TFont

TScreen


The command-line compiler
The command-line compiler1054001

Section topics	参照

Delphiのコマンドラインコンパイラ (DCC32.EXE) を使うと，DOS コマンドラインからIDE コンパイラ (DELPHI.EXE) のすべての機能を呼び出すことができます。コマンドラインコンパイラは，DOS プロンプトから次の構文を使って実行します。

DCC32 [options] filename [options]

options はコンパイラに情報を与えるパラメータ (ない場合もある)，filename はコンパイルするソースファイルの名前です。DCC32 とだけ入力すると，コマンドラインオプションと構文のヘルプ画面が表示されます。

filenale に拡張子がない場合，コマンドラインコンパイラはそのファイルを .DPR とみなし，.DPR ファイルが見つからなければ .PAS を探します。拡張子のないファイルをコンパイルする場合は，ファイル名の最後にピリオド (.) を付ける必要があります。

ファイルの内容がプログラムのソースコードテキストの場合，コンパイラは filename.EXE という実行形式ファイルを作成します。ファイルの内容がライブラリの場合は filename.DLL というファイルを作成します。また，内容がパッケージの場合は filename.DPL，ユニットの場合は filename.DCU を作成します。

コマンドラインコンパイラには複数のオプションを指定できます。各オプションは，スラッシュ (/) の後にオプション文字が続きます。オプションの種類によって，オプション文字の後に数字やシンボル，ディレクトリ名などの追加情報が続くこともあります。オプションは，ファイル名の前または後に任意の順序で指定できます。


Command-line compiler options
Command-line compiler options1054002

Section topics	参照

IDE では，メニューからさまざまなオプションを設定できます。コマンドラインコンパイラでは，これらのオプションをスラッシュ (/) で区切って指定します。スラッシュ (/) のかわりにハイフン (-) を使うこともできますが，ハイフンで始まるオプションは空白で区切る必要があります。たとえば，次の 2 つのコマンドラインは同じ内容であり，ともに有効です。

DCC -IC:\DELPHI -DDEBUG SORTNAME -$R- -$U+

DCC /IC:\DELPHI/DDEBUG SORTNAME /$R-/$U+

最初のコマンドラインではハイフンを使用しており，空白でオプションを区切っています。2 番目のコマンドラインではスラッシュを使用しているので，空白で区切る必要はありません。

表は，コマンドラインオプションのリストです。これらのオプションのほかにも，次の節で解説するように 1 文字のコンパイラ指令をコマンドラインに指定することができます。

オプション	説明
/Aunit=alias	ユニットのエリアス設定
/B	すべてのユニットの構築
/CC	コンソールアプリケーションの作成
/CG	GUI アプリケーションの作成
/Ddefines	条件シンボルの定義
/Epath	EXE のディレクトリ
/Faddress	実行時エラーの検出
/GS	セグメント付きマップファイル
/GP	パブリック付きマップファイル
/GD	詳細マップファイル
/H	ヒントメッセージの表示
/Ipaths	インクルードディレクトリ
/J	OBJ ファイルの作成
/JP	C++ OBJ ファイルの作成
/Kaddress	イメージベースアドレスの設定
/LEpath	パッケージの DPL ディレクトリ
/LNpath	パッケージの DCP ディレクトリ
/LUpackage	パッケージの使用
/M	メイク (変更ユニットのみ再コンパイル)
/Npath	DCU ディレクトリ
/Opaths	オブジェクトファイルディレクトリ
/P	8.3 ファイル名も検索
/Q	Quiet モードコンパイル
/Rpaths	リソースファイルディレクトリ
/TXext	ターゲットファイル拡張子
/Upaths	ユニットファイルディレクトリ
/V	Turbo Debugger デバッグ情報
/W	警告メッセージの出力
/Z	暗黙のコンパイルの抑止
コマンドラインに DCC32 だけを入力すると，コマンドラインコンパイラの構文とオプションの一覧が表示されます。


Compiler directive options
Compiler directive options1054003

Section topics	参照

Delphi では，多数のコンパイラ指令をサポートします。各コンパイラ指令については「コンパイラ指令」で解説されています。/$ と /D コマンドラインオプションを使用すると，ほとんどのコンパイラ指令のデフォルト状態を変更することができます。コマンドラインで /$ と /D を使用するのは，コンパイルされた各ソースファイルの最初に対応するコンパイラ指令を挿入するのと同じです。

The switch directive option1054004

/$ オプションを使うと，すべてのスイッチ指令のデフォルト状態を変更できます。スイッチ指令オプションの構文は，/$ の後に指令文字が続き，その後に正符号 (+) または負符号 (�) が続きます。たとえば次のようになります。

DCC32 MYSTUFF /$R-

これは，MYSTUFF.PAS を範囲チェックオフでコンパイルします。

DCC32 MYSTUFF /$R+

この場合は，範囲チェックオンでコンパイルします。ソーステキストに {$R+} または {$R-} コンパイラ指令があると /$R コマンドラインオプションがオーバーライドされることに注意してください。

/$ オプションを繰り返し使用して複数のコンパイラ指令を指定できます。

DCC32 MYSTUFF /$R-/$I-/$V-/$U+

また，$M 以外のコンパイラ指令は，カンマで区切って記述することもできます。

DCC32 MYSTUFF /$R-,I-,V-,U+

ドル記号 ($) は 1 つだけ記述します。

形式上の理由から，$M 指令はカンマで区切ってコンパイラ指令リストに記述することはできません。

The conditional defines option1054005

/D オプションを使うと，{$DEFINE symbol} コンパイラ指令に対応する条件シンボルを定義することができます。/D オプションでは，セミコロン (;) で区切った1 つまたは複数の条件シンボルを続けて記述しなければなりません。

DCC32 MYSTUFF /DIOCHECK;DEBUG;LIST

たとえば，上記のコマンドラインは，MYSTUFF.PAS のコンパイルで IOCHECK，DEBUG，および LIST の 3 つの条件シンボルを定義しています。これは，MYSTUFF.PAS の始めに次のコードを挿入するのと同じです。

{$DEFINE IOCHECK}

{$DEFINE DEBUG}

{$DEFINE LIST}

複数の /D 指令を指定する場合，シンボルリストを結合することができます。したがって，次のコードも最初の例と同じです。

DCC32 MYSTUFF /DIOCHECK/DDEBUG/DLIST


Compiler mode options
Compiler mode options1054006

Section topics	参照

コンパイラ自体の機能に影響するオプションもあります。他のオプションの場合と同様に，これらもハイフンまたはスラッシュ付きの形式で使用できます。オプションを区切るために少なくとも1 文字分の空白を入れるのを忘れないでください。

The make (/M) option1054007

コマンドラインコンパイラには，プロジェクトの管理を支援する MAKE 機能が組み込まれています。/M オプションを使うと，コンパイルするファイルが依存するすべてのユニットがチェックされます。このオプションを使うとコンパイル時間が短くなります。

ユニットは，次の場合に再コンパイルされます。

ユニットファイルが作成された後で，ユニットのソースファイルが変更された場合

$I 指令に含まれるファイル，$L 指令によりリンクされる .OBJ ファイル，$R 指令により参照される .RES ファイルのいずれかが，ユニットファイルよりも新しい場合

uses 文で参照されているユニットの interface 部が変更された場合

/Z オプションでコンパイルされたユニットは MAKE の対象から除外されます。

このオプションを上記の例に適用すると，コマンドは次のようになります。

DCC32 MYSTUFF /M

The build all (/B) option1054008

/M オプションは更新する必要のあるファイルだけをコンパイルしますが，/B オプションを使うと，プログラムが依存するすべてのユニットが更新されます。ただし，/M オプションと /B オプションを同時に使用することはできません。

/B オプションは，/M オプションよりも処理に時間がかかり，通常は不要です。

このオプションを上記の例に適用すると，コマンドは次のようになります。

DCC32 MYSTUFF /B

The find error (/F) option1054009

実行時エラーのためにプログラムが終了したときは，エラーコードとエラーが起きたアドレスが表示されます。/Faddress オプションでそのアドレスを指定すると，プログラムとユニットが ($D コンパイラ指令により) デバッグ情報付きでコンパイルされていれば，エラーを起こした文のソーステキスト内の位置がわかります。

コマンドラインコンパイラが /F オプションで実行時エラーを検出するためには，プログラムをすべて初めてコンパイルしたときに使用したのと同じコマンドラインパラメータでコンパイルする必要があります。

前述のように，プログラムとユニットはデバッグ情報付きでコンパイルされていないと実行時エラーを検出できません。デフォルトでは，すべてのプログラムとユニットはデバッグ情報付きでコンパイルされますが，{$D-} コンパイラ指令や /$D- オプションでオフにした場合は，コマンドラインコンパイラは実行時エラーの場所を特定できなくなります。

The use packages (/LU) option1054010

コンパイルするアプリケーションで使用する実行時パッケージリストを指定するには，/LU オプションを使います。Delphi のプロジェクトオプションダイアログにすでに指定してある実行時パッケージは，コマンドラインで繰り返す必要がありません。

The disable implicit compilation (/Z) option1054011

/Z オプションは，パッケージとユニットが後で暗黙に再コンパイルされるのを防ぎます。パッケージの場合，このオプションは .DPK ファイルで {$IMPLICITBUILD OFF} を指定するのと同じです。構築のたびに変更されることがなかったり，ソースコードを配布する予定のない，低レベルの機能を提供するパッケージのコンパイルには /Z オプションを使用します。

The target file extension (/TX) option1054012

/TX オプションを使うと，出力ファイルのデフォルトの拡張子を変更できます。

DCC32 MYSTUFF /TXSYS

この例では，コンパイル出力が MYSTUFF.SYS というファイルに生成されます。

The quiet (/Q) option1054013

Quiet モードオプションは，コンパイル中にファイル名と行番号の表示を抑止します。たとえば，次のようにこのオプションを指定すると，

DCC32 MYSTUFF /Q

出力されるのは，起動時の著作権メッセージと終了時のコンパイル結果の情報だけです。エラーが生じた場合は報告されます。


Directory options
Directory options1054014

Section topics	参照

いくつかのオプションでは，コマンドラインコンパイラが使用するディレクトリリストを指定することができます。これらは，組み込み (/I)，DCU 入力 (ユニットの検索パス，/U)，リソース (/R)，オブジェクト (/O)，EXE と DCU 出力 (/E)，そして DCU 出力 (/N) です。

一部のオプションでは，セミコロンで区切って複数のディレクトリを指定できます。次のコマンドラインは，カレントディレクトリを検索した後，C:\DELPHI\INCLUDE と D:\INC 内でインクルードファイルを検索するようにコマンドラインコンパイラに指示しています。

DCC32 MYSTUFF /IC:\DELPHI\INCLUDE;D:\INC

複数のディレクトリを指定すると，ディレクトリリストは結合されます。したがって，次のコマンドラインは最初の例と同じです。

DCC32 MYSTUFF /IC:\DELPHI\INCLUDE /ID:\INC

The EXE directory (/E) option1054015

このオプションを使うと，作成した .EXE ファイルを置く場所をコマンドラインコンパイラに指示できます。ここでは，ディレクトリパスを引数とします。

DCC32 MYSTUFF /EC:\DELPHI\BIN

1 つの EXE ディレクトリだけを指定できます。このディレクトリは .DLL ファイルにも使用されます。/E オプションは，.DPL (パッケージ) ファイルの位置には影響しません。

このようなオプションが指定されない場合，コマンドラインコンパイラは，.EXE ファイルを対応するソースファイルと同じディレクトリに作成します。

The package DPL directory (/LE) option1054016

このオプションを使うと，パッケージをコンパイルしたときに作成した .DPL ファイルを置く場所をコマンドラインコンパイラに指示できます。構文は /E と同じです。

The package DCP directory (/LN) option1054017

このオプションを使うと，パッケージをコンパイルしたときに作成した .DCP ファイルを置く場所をコマンドラインコンパイラに指示できます。構文は /E と同じです。

The DCU directory (/N) option1054018

このオプションを使うと，ユニットをコンパイルしたときに作成した .DCU ファイルを置く場所をコマンドラインコンパイラに指示できます。構文は /E と同じです。

The include directories (/I) option1054019

Delphi では，{$I filename} コンパイラ指令でインクルードファイルを指定します。 /I オプションを使うと，インクルードファイルを検索するディレクトリリストを指定できます。

The unit directories (/U) option1054020

ユニットを使用してプログラムをコンパイルするとき，コマンドラインコンパイラはカレントディレクトリでユニットファイルを検索します。/U オプションを使うと，ユニットを検索するディレクトリを追加できます。

The resource directories (/R) option1054021

DCC32 は，カレントディレクトリでリソースファイルを検索します。/R オプションを使うと，DCC32 がリソースファイルを検索するディレクトリを追加して指定できます。

The object files directories (/O) option1054022

Delphi では，{$L filename} コンパイラ指令を使って Borland C++ のような外部の他のコンパイラやアセンブラが作成したマシンコードを含む .OBJ ファイルをリンクすることができます。/O オプションを使うと，このような .OBJ ファイルを検索するディレクトリリストを指定できます。


Debug options
Debug options1054023

Section topics	参照

コマンドラインコンパイラには，外部デバッグ情報の生成を可能にする2 つのコマンドラインオプションがあります。それは，マップファイルオプションと Turbo Debugger のデバッグ情報オプションです。

The map file (/G) option1054024

/G オプションは，.EXE ファイルのレイアウトを示す .MAP ファイルを生成するようコマンドラインコンパイラに指示します。.EXE や .DCU ファイルのバイナリフォーマットとは異なり，.MAP ファイルはプリンタに出力したりエディタに読み込んだりできる判読可能なテキストファイルです。/G オプションには，S，P，または D の文字を続けて指定し，.MAP ファイル内の情報レベルを指定します。.MAP ファイルは次の 3 つのセクションに分かれています。

セグメント

パブリック

行番号

/GS オプションはセグメントセクションだけを出力します。/GP はセグメントとパブリックセクションを出力し，/GD は3 つのセクションをすべて出力します。

{$D+,L+} 状態 (デフォルト) でコンパイルされたモジュール (プログラムとユニット) の場合，パブリックセクションにはグローバルのすべての変数，手続き，および関数が表示され，行番号セクションにはモジュールのすべての手続きと関数の行番号が表示されます。{$D+,L-} 状態では，ユニットの interface 部に定義されたシンボルだけがパブリックセクションにリストされます。{$D-} 状態でコンパイルされたモジュールの場合，行番号セクションには項目がありません。

The generate Turbo Debugger debug info (/V) option1054025

コマンドラインで /V オプションを指定すると，コマンドラインコンパイラは，Turbo Debugger 5.0 互換の外部デバッグ情報を .EXE ファイルの最後に付加します。Turbo Debugger では，ソースレベルとマシンレベル両方のデバッグが行え，強力なブレークポイントが使用できます。

/V により生成されるデバッグ情報は .EXE ファイルのサイズを増加させますが，.EXE ファイルの実際のコードには影響しません。また，プログラムを実行するための追加メモリも必要としません。

.EXE ファイルに付加されるデバッグ情報のサイズは，アプリケーションを構成する各モジュール (プログラムとユニット) の $D および $L コンパイラ指令の設定により異なります。デフォルトの {$D+,L+} 状態でコンパイルされたモジュールの場合，すべての定数，変数，型，手続き，関数シンボルの情報がデバッガに伝わります。{$D+,L-} 状態では，ユニットの interface 部に定義されたシンボル情報だけがデバッガに伝わります。{$D-} 状態の場合は行番号レコードが生成されないので，アプリケーションをデバッグしたときにデバッガはソース行を表示できません。

IDE 内部デバッガは，Turbo Debugger デバッグ情報を使用しません。TD デバッグ情報を生成するとコンパイル/リンク時間が約 2 倍かかるため，TD でアプリケーションをデバッグする場合以外は，TD デバッグ情報はオフにしておきます。


The DCC32.CFG file
The DCC32.CFG file1054026

Section topics	参照

オプションのリストは，DCC32.CFG というコンフィギュレーションファイルに設定しておくことができます。このコンフィギュレーションファイルは，コマンドラインに入力したオプションのほかに使用されます。コンフィギュレーションファイルの各行は，コマンドラインで直接指定される実際のコマンドライン引数の前に挿入される追加のコマンドライン引数として扱われます。したがって，コンフィギュレーションファイルを作成することにより，コマンドラインオプションのデフォルト設定を変更することができます。

1 回のコマンドラインで同じコマンドラインオプションを何回でも指定できますが，最後のオプション以外は無視されます。そのため，コンフィギュレーションファイルで設定を変更していても，実際のコマンドラインでさらに変更することができます。

DCC32 は起動時にカレントディレクトリで DCC32.CFG を探します。カレントディレクトリで見つからない場合は，DCC32.EXE があるディレクトリを探します。

DCC32.CFG 内でスラッシュ (/) またはハイフン (-) で始まっていない行は，コンパイルするデフォルトのファイル名を定義することになります。このとき，空のコマンドラインで (またはコマンドラインオプションだけで，ファイル名のないコマンドラインで) DCC32 を起動すると，構文の要約は表示されず，デフォルトファイル名でコンパイルが行われます。

次に示す DCC32.CFG ファイルの例では，インクルードファイル，オブジェクトファイル，およびユニットファイルのディレクトリを定義し，$F と $S コンパイラ指令のデフォルト状態を変更しています。

/IC:\DELPHI\INC;C:\DELPHI\SRC

/OC:\DELPHI\ASM

/UC:\DELPHI\UNITS

/$F+

/$S-

ここで，システムプロンプトに次のように入力すると，

DCC32 MYSTUFF

DCC32 は，次のように入力された場合と同じように動作します。

DCC32 /IC:\DELPHI\INC;C:\DELPHI\SRC /OC:\DELPHI\ASM /UC:\DELPHI\UNITS /$F+ /$S- MYSTUFF


See also1054027

コンパイラ指令


Compiler directives
Compiler directives1056001

Section topics	参照

この付録では，Delphi コンパイラ機能の制御に使用するコンパイラ指令について解説します。コンパイラ指令の説明はアルファベット順になっています。各コンパイラ指令は，スイッチ，パラメータ，条件コンパイル指令のいずれかに分類されます。コンパイラ指令のリストの後に条件コンパイル指令の使い方について簡単な説明があります。ここでは，条件の指示や記号を使って同じソーステキストからさまざまなコードを作成する方法を解説しています。

コンパイラ指令は特殊な構文を持つコメントです。Delphi では，コメントが使用できる場所であればどこでもコンパイラ指令が使用できます。コンパイラ指令は，コメント開始記号に続く $ で始まり，その直後に個々の指令を示す名前 (1 文字または 2 文字) が続きます。指令の後には，コメントテキストや必要なパラメータを記述できます。

この付録では，次の 3 つの種類の指令について説明します。

スイッチ指令は，特定のコンパイラ機能をオンまたはオフにします。1 文字のバージョンの場合，指令文字のすぐ後に + または - を追加します。長い文字のバージョンの場合は，ON または OFF を追加します。

スイッチ指令は，グローバルまたはローカルのいずれかです。

グローバル指令は，コンパイル全体に影響します。プログラムの宣言部またはコンパイルされるユニットの前に必ず指定します。

ローカル指令は，次に同じ指令が起きるまでコンパイルの一部にだけ影響します。どこにでも記述できます。

スイッチ指令は，空白を入れずにカンマで区切り，1 つのコンパイラ指令のコメントの中でグループ化することができます。たとえば次のように記述できます。

  {$B+,R-,S-}

パラメータ指令は，ファイル名やメモリサイズのようにコンパイルに影響するパラメータを指定します。

条件指令は，ユーザーが定義できる条件記号に基づいて，ソーステキストの一部の条件コンパイルを制御します。条件指令の使い方についての詳細は「条件コンパイル指令の使い方」を参照してください。

スイッチ指令以外のすべての指令には，指令名とパラメータの間に少なくとも 1 文字の空白が必要です。コンパイラ指令の例を示します。

{$B+}

{$STACKCHECKS ON}

{$R- Turn off range checking}

{$I TYPES.INC}

{$M 32768,4096}

{$DEFINE Debug}

{$IFDEF Debug}

{$ENDIF}

コンパイラ指令はソースコードに直接挿入できます。コマンドラインコンパイラ (DCC32.EXE) と IDE (DELPHI32.EXE) は，どちらもデフォルト指令を変更することができます。

［プロジェクトオプション］ダイアログボックスの［コンパイラ］ページには，多数のコンパイラ指令に対応するオプションが含まれています。ここでの設定を変更すると，そのプロジェクトの以降のコンパイルでソースコードが再コンパイルされるたびにすべてのユニットに影響します。コンパイラスイッチを変更してコンパイル (作成) すると，変更の影響を受けるユニットはあリません。すべて構築 (Build All) にすると，すべての (ソースコードのある) ユニットは新しい設定で再コンパイルされます。

コマンドラインコンパイラを使用すると，コマンドラインでコンパイラ指令を指定することができます (たとえば，DCC32 /$R+ MYPROG)。あるいはコンフィギュレーションファイルに指令を書き込むこともできます (「DCC32.CFG ファイル」参照)。ソースコードのコンパイラ指令は，コマンドラインのコンパイラ指令および IDE のプロジェクトオプションに常に優先します。

Delphi のエディタで作業していて，どのコンパイラ指令が有効であるか速く知りたい場合には，〔Ctrl〕+〔O〕，〔O〕を押します。すると Delphi は，編集ウィンドウ内のファイルの先頭に現在の設定を挿入します。


Align fields
Align fields1056002

Section topics	参照

種類	スイッチ
構文	{$A+} または {$A-} {$ALIGN ON} または {$ALIGN OFF}
デフォルト	{$A+} {$ALIGN ON}
スコープ	ローカル
説明

$A 指令はレコード型のフィールドのアラインメントを制御します。

{$A+} 状態にすると，packed 修飾子を付けずに宣言されたレコード型のフィールドがアラインメントされます。{$A-} 状態では，レコード型のフィールドはアラインメントされません。レコード型フィールドのアラインメントについては『Object Pascal 言語ガイド』を参照してください。

$A 指令の状態にかかわらず，変数と型付き定数は常に最適にアクセスされるようにアラインメントされます。{$A+} 状態の方が実行速度は上がります。


Application type
Application type1056003

Section topics	参照

種類	パラメータ
構文	{$APPTYPE GUI} または {$APPTYPE CONSOLE}
デフォルト	{$APPTYPE GUI}
スコープ	グローバル
説明

$APPTYPE 指令は，Win32 コンソールまたは GUI アプリケーションを生成するかどうかを制御します。「/CC」の /C コンパイラオプションも参照してください。

{$APPTYPE GUI} 状態にすると，コンパイラは GUI アプリケーションを生成します。これは，Delphi アプリケーションの通常の状態です。

{$APPTYPE CONSOLE} 状態では，コンパイラはコンソールアプリケーションを生成します。コンソールアプリケーションが起動されると，Windows はユーザーがアプリケーションと対話できるテキストモードのコンソールウィンドウを作成します。入力および出力標準テキストファイルは，自動的にコンソールアプリケーションのコンソールウィンドウに関連付けられます。

System ユニットで宣言される IsConsole 論理変数を使うと，プログラムがコンソールアプリケーションとしてコンパイルされたか，GUI アプリケーションとしてコンパイルされたるかを検出できます。

$APPTYPE 指令はプログラムに対してのみ意味を持ちます。ライブラリ，ユニット，あるいはパッケージでは使用できません。


Assert directives
Assert directives1056004

Section topics	参照

種類	スイッチ
構文	{$C+} または {$C-} {$ASSERTIONS ON} または {$ASSERTIONS OFF}
デフォルト	{$C+} {$ASSERTIONS ON}
スコープ	ローカル
説明

$C 指令は，ソースファイルのアサート用のコード生成を使用可能または使用不可にします。{$C+} はデフォルトです。

製品となったバージョンでは実行時にアサートが起きても意味がないため，実行速度を上げるためにも，{$C-} としてアサートを無効にすることをお勧めします。


Boolean short-circuit evaluation
Boolean short-circuit evaluation1056005

Section topics	参照

種類	スイッチ
構文	{$B+} または {$B-} {$BOOLEVAL ON} または {$BOOLEVAL OFF}
デフォルト	{$B-} {$BOOLEVAL OFF}
スコープ	ローカル
説明

$B 指令は，and と or 論理演算子に対する 2 種類のコード生成法のどちらかを選択します。

{$B+} 状態にすると，コンパイラは論理式の完全評価を行うコードを生成します。その場合，式全体の結果がすでにわかっていても，and と or 演算子からなる論理式のすべてのオペランドが必ず評価されます。

{$B-} 状態にすると，コンパイラはショートサーキット論理式評価を行うコードを生成します。これは，左から右に評価していく際に，式全体の結果が明らかになった時点で評価が停止されることを意味します。

詳細については『Object Pascal 言語ガイド』の第 6 章の「論理演算子」の節を参照してください。


Debug information
Debug information1056006

Section topics	参照

種類	スイッチ
構文	{$D+} または {$D-} {$DEBUGINFO ON} または {$DEBUGINFO OFF}
デフォルト	{$D+} {$DEBUGINFO ON}
スコープ	グローバル
説明

$D 指令は，デバッグ情報の生成をオンまたはオフにします。この情報には，各手続きの行番号テーブルが含まれ，オブジェクトコードアドレスをソーステキストの行番号にマップするのに使用されます。

ユニットの場合，デバッグ情報はユニットのオブジェクトコードとともにユニットファイルに記録されています。デバッグ情報があると，ユニットファイルサイズが増加し，このユニットを使用するプログラムをコンパイルするときに追加メモリが必要ですが，実行可能プログラムのサイズや速度には影響しません。

プログラムやユニットが {$D+} 状態でコンパイルされると，Delphi の統合デバッガでステップ単位の実行が可能になり，そのモジュールのブレークポイントが設定できます。

［プロジェクトオプション］ダイアログボックスの［リンカ］ページの［TD32 デバッグ情報を含める］オプションと［マップファイル］オプションは，モジュールを {$D+} 状態でコンパイルした場合だけ，指定したモジュールの完全なソース行情報を作成します。

$D スイッチは一般的に $L スイッチとともに使用されます。$L スイッチは，デバッグのローカルシンボル情報の生成をオンまたはオフにします。「Turbo Debugger デバッグ情報生成 (/V) オプション」および「シンボルのクロスリファレンス情報」も参照してください。


DEFINE directive
DEFINE directive1056007

Section topics	参照

種類	条件コンパイル
構文	{$DEFINE name}
説明

名前 (name) を指定して条件シンボルを定義します。シンボルは，シンボルを宣言した現在のモジュールがコンパイルされている間，または {$UNDEF name} 指令が記述されるまで認識されます。名前がすでに定義されていると，{$DEFINE name} 指令は無効です。


DENYPACKAGEUNIT directive
DENYPACKAGEUNIT directive1056008

Section topics	参照

種類	スイッチ
構文	{$DENYPACKAGEUNIT ON} または {$DENYPACKAGEUNIT OFF}
デフォルト	{$DENYPACKAGEUNIT OFF}
スコープ	ローカル
説明

{$DENYPACKAGEUNIT ON} 指令を使うと，ユニットがパッケージに含まれることを防ぎます。


Description
Description1056009

Section topics	参照

種類	パラメータ
構文	{{$DESCRIPTION 'text'}
スコープ	グローバル
説明

$D 指令は，指定したテキストを .EXE，.DLL，または .DPL のリソースに挿入します。慣例上，テキストには名前，バージョン番号，著作権情報を記述しますが，任意のテキストを指定することができます。たとえば次のように記述します。

{$D 'My Application version 12.5'}

テキストの長さは 256 バイトまでで，引用符で囲みます。この説明はエンドユーザーには表示されません。実行可能ファイルに，エンドユーザーの役に立つ説明テキスト，バージョン，著作権情報を記述するには，バージョン情報リソースを使用します。

メモ

説明のテキストは引用符で囲まなければなりません。


DESIGNONLY directive
DESIGNONLY directive1056010

Section topics	参照

種類	スイッチ
構文	{$DESIGNONLY ON} または {$DESIGNONLY OFF}
デフォルト	{$DESIGNONLY OFF}
スコープ	ローカル
説明

{$DESIGNONLY ON} 指令を使うと，この指令を出したパッケージが Delphi IDE でインストール用にコンパイルされます。詳細は『Object Pascal 言語ガイド』の第 14 章「パッケージ独自のコンパイラ指令」を参照してください。

DESIGNONLY 指令は .DPK ファイルにだけ置くことができます。


ELSE directive
ELSE directive1056011

Section topics	参照

種類	条件コンパイル
構文	{$ELSE}
説明

前の {$IFxxx} と次の {$ENDIF} で区切られたソーステキストの，コンパイルと無視とを切り替えます。


ENDIF directive
ENDIF directive1056012

Section topics	参照

種類	条件コンパイル
構文	{$ENDIF}
説明

最後の {$IFxxx} 指令で開始された条件コンパイルを終了します。


Extended syntax
Extended syntax1056013

Section topics	参照

種類	スイッチ
構文	{$X+} または {$X-} {$EXTENDEDSYNTAX ON} または {$EXTENDEDSYNTAX OFF}
デフォルト	{$X+} {$EXTENDEDSYNTAX ON}
スコープ	グローバル
説明

$X 指令は，次の Delphi の拡張構文を有効または無効にします。

関数文。{$X+} モードでは，関数の呼び出しは手続きの呼び出しとして使えます。すなわち，関数呼び出しの結果は廃棄することができます。一般的には，関数が実行する計算は結果によって表されます。したがって，結果を廃棄してしまっては意味がありません。しかし，関数がパラメータに基づいて複数の計算を実行できる場合には，結果が役に立たないこともあります。このようなとき，{$X+} 拡張オプションを使用すると，関数は手続きとして扱われます。

ヌルで終わる文字列。{$X+} コンパイラ指令は，組み込みの PChar 型とゼロベース文字配列に適用される特別な規則を有効にして，Delphi がヌルで終わる文字列をサポートできるようにします。ヌルで終わる文字列についての詳細は，『Object Pascal 言語ガイド』の第 17 章「ヌルで終わる文字列」を参照してください。

メモ	$X 指令は，Borland Pascal の前のバージョンとの下位互換性を提供します。Delphi のアプリケーションを記述するときは，{$X-} モードを使用してはなりません。


Hints
Hints1056014

Section topics	参照

種類	スイッチ
構文	{$HINTS ON} または {$HINTS OFF}
デフォルト	{$HINTS ON}
スコープ	ローカル
説明

$HINTS 指令は，コンパイラによるヒントメッセージの生成を制御します。

{$HINTS ON} 状態にすると，未使用の変数や代入，決して実行されない for ループや while ループなどを検出すると，コンパイラはヒントメッセージを出力します。{$HINTS OFF} 状態にすると，コンパイラはヒントメッセージを生成しません。

{$HINTS OFF} と {$HINTS ON} 指令の間にコードを置くと，関係のないヒントはオフにすることができます。たとえば次のように記述します。

{$HINTS OFF}

procedure Test;

var

  I: Integer;

begin

end;

{$HINTS ON}

$HINTS 指令があるため，コンパイラは上記の手続きをコンパイルするときに，未使用の変数のヒントを生成しません。


Implicit Build
Implicit Build1056015

Section topics	参照

種類	スイッチ
構文	{$IMPLICITBUILD ON} または {$IMPLICITBUILD OFF}
デフォルト	{$IMPLICITBUILD ON}
スコープ	グローバル
説明

{$IMPLICITBUILD OFF} はパッケージ専用の指令で，この指令の書かれたソースファイルが後で暗黙に再コンパイルされるのを抑止します。構築後めったに変更されない，またはソースコードが配布されることのない低レベル機能を提供するパッケージをコンパイルするときには，.DPK ファイルで {$IMPLICITBUILD OFF} を使用します。ユニットソースファイルでの {$IMPLICITBUILD OFF} の使用はお勧めしません。「暗黙のコンパイルの抑止 (/Z) オプション」も参照してください。


Imported data
Imported data1056016

Section topics	参照

種類	スイッチ
構文	{$G+} または {$G-} {$IMPORTEDDATA ON} または {$IMPORTEDDATA OFF}
デフォルト	{$G+} {$IMPORTEDDATA ON}
スコープ	ローカル
説明

{$G-} 指令は，インポートしたデータ参照の作成を不可にします。{$G-} を使うと，メモリアクセス効率が向上しますが，この指令の書かれたパッケージユニットはほかのパッケージの変数を参照できません。


IFDEF directive
IFDEF directive1056017

Section topics	参照

種類	条件コンパイル
構文	{$IFDEF name}
説明

name が定義されている場合，この後に続くソーステキストをコンパイルします。


IFNDEF directive
IFNDEF directive1056018

Section topics	参照

種類	条件コンパイル
構文	{$IFNDEF name}
説明

name が定義されていない場合，この後に続くソーステキストをコンパイルします。


IFOPT directive
IFOPT directive1056019

Section topics	参照

種類	条件コンパイル
構文	{$IFOPT switch}
説明

switch が現在指定した状態にある場合，この後に続くソーステキストがコンパイルされます。switch には，スイッチオプションの名前を指定し，後に + または - 記号が続きます。たとえば次のように記述します。

{$IFOPT R+}

  Writeln('Compiled with range-checking');

{$ENDIF}

この例では，$R オプションが現在有効であれば Writeln 文がコンパイルされます。


Image base address
Image base address1056020

Section topics	参照

種類	パラメータ
構文	{$IMAGEBASE number}
デフォルト	{$IMAGEBASE $00400000}
スコープ	グローバル
説明

$IMAGEBASE 指令は，アプリケーション，DLL，または DPL を読み込むデフォルトのアドレスを制御します。数字の引数は，イメージベースアドレスを指定する 32 ビットの整数値でなければなりません。また，数字の引数は $00010000 以上でなければならず，16 ビットより小さい部分は無視され，ゼロとみなされます。

モジュール (アプリケーションまたはライブラリ) がプロセスのアドレススペースに読み込まれると，Windows はモジュールをそのデフォルトイメージアドレスに置こうとします。これに失敗した場合，すなわち指定アドレスが既に別のモジュールに使用されていた場合，モジュールは Windows が実行時に決定したアドレスに再度読み込まれます。

アプリケーションのイメージベースアドレスを変更することはめったにありません。しかし，ライブラリの場合には，デフォルトイメージベースアドレスの $00400000 がほとんど確実に使用できないため，$IMAGEBASE 指令を使ってデフォルト以外のイメージベースアドレスを指定することを薦めます。DLL イメージの推奨アドレス範囲は，$40000000～$7FFF0000 です。この範囲のアドレスは，Windows NT および Windows 95 の両方のプロセスにおいて必ず使用できます。

Windows がイメージベースアドレスでの DLL (または DPL) の読み込みに成功すると，移動の調整が必要なくなるため，読み込み時間が少なくなります。さらに，ライブラリを使用する複数のプロセスで指定したアドレス範囲を使用できる場合，DLL のイメージの code 部をプロセス間で共有することができます。したがって，読み込み時間もメモリ消費量も削減されます。

メモ	$IMAGEBASE 指令は，/K コマンドラインコンパイラ指令オプションにより供給される値をすべてオーバーライドします。


Include file
Include file1056021

Section topics	参照

種類	パラメータ
構文	{$I filename} {$INCLUDE filename}
スコープ	ローカル
説明

$I パラメータ指令は，指定したファイルをコンパイルに含めるようにコンパイラに指示します。実際には，ファイルは {$I filename} 指令のすぐ後のコンパイルテキストに挿入されます。ファイル名のデフォルトの拡張子は，.PAS です。ファイル名にディレクトリパスが指定されていない場合，現在のモジュールと同じディレクトリでファイルを検索するほかに，Delphi は，［プロジェクトオプション］ダイアログボックスの［ディレクトリ/条件］ページの［検索パス(S)］ボックスに指定されているディレクトリ (または DCC32 コマンドラインの /I オプションで指定されるディレクトリ) も検索します。

インクルードファイルの使用には 1 つだけ制限があります。それは，インクルードファイル指令を実行部の中央に指定することはできないということです。実行部の begin から end までのすべての文は同じソースファイルの中になければなりません。


Input/output checking
Input/output checking1056022

Section topics	参照

種類	スイッチ
構文	{$I+} または {$I-} {$IOCHECKS ON} または {$IOCHECKS OFF}
デフォルト	{$I+} {$IOCHECKS ON}
スコープ	ローカル
説明

$I スイッチ指令は，I/O 手続きへの呼び出し結果をチェックするコードの自動生成を使用可能または使用不可にします。I/O 手続きについては，『Object Pascal 言語ガイド』 で解説しています。このスイッチが オンのときに I/O 手続きがゼロ以外の I/O 結果を返すと，EInOutError 例外が生じます (または，例外ハンドラが使用不可の場合にはプログラムは終了します)。このスイッチがオフのときは，IOResult を呼び出して I/O エラーをチェックする必要があります。


Link object file
Link object file1056023

Section topics	参照

種類	パラメータ
構文	{$L filename} {$LINK filename}
スコープ	ローカル
説明

$L パラメータは，指定したファイルを，コンパイルされるプログラムまたはユニットにリンクするようにコンパイラに指示します。$L 指令は，外部であると宣言された手続きと関数に他の言語で記述されたコードをリンクさせるために使用されます。指定されたファイルは，Intel 形式のリロケータブルオブジェクトファイル (.OBJ ファイル) でなければなりません。ファイル名のデフォルトの拡張子は .OBJ です。ファイル名がディレクトリパスを指定していない場合，現在のモジュールと同じディレクトリでファイルを検索するほかに，Delphi は，［プロジェクトオプション］ダイアログボックスの［ディレクトリ/条件］ページの［検索パス(S)］入力ボックスに指定されているディレクトリ (または DCC32 コマンドラインの /O オプションで指定されるディレクトリ) も検索します。アセンブリ言語とのリンクについての詳細はオンラインヘルプを参照してください。


Local symbol information
Local symbol information1056024

Section topics	参照

種類	スイッチ
構文	{$L+} または {$L-} {$LOCALSYMBOLS ON} または {$LOCALSYMBOLS OFF}
デフォルト	{$L+} {$LOCALSYMBOLS ON}
スコープ	グローバル
説明

$L スイッチ指令は，ローカルシンボル情報の生成をオンまたはオフにします。ローカルシンボル情報には，モジュール内のすべてのローカル変数の名前と型，そして定数が含まれます。すなわち，モジュールの implementation 部のシンボルと，モジュールの手続きおよび関数内のシンボルが含まれます。

ユニットの場合，ローカルシンボル情報は，ユニットのオブジェクトコードと一緒にユニットファイルに記録されます。ローカルシンボル情報が含まれるとユニットファイルのサイズが増加し，そのユニットを使用するプログラムのコンパイル時に追加メモリが必要になりますが，実行可能プログラムのサイズや速度には影響しません。

プログラムまたはユニットを {$L+} 状態でコンパイルすると，Delphi の統合デバッガでモジュールのローカル変数を調べたり変更できるようになります。さらに，モジュールの手続きや関数の呼び出しを［表示(V)｜呼び出し履歴(C)］で調べることができます。

［プロジェクトオプション］ダイアログボックスの［リンカ］ページの［TD32 デバッグ情報を含める］と［マップファイル］オプションを選択している場合，指定したモジュールを {$L+} 状態でコンパイルしていれば，そのモジュールのローカルシンボル情報が作成されます。

$L スイッチは通常 $D スイッチとともに使用され，デバッグ用の行番号テーブルの生成をオンまたはオフにします。{$D-} 状態の場合は $L 指令は無視されます。


Long strings
Long strings1056025

Section topics	参照

種類	スイッチ
構文	{$H+} または {$H-} {$LONGSTRINGS ON} または {$LONGSTRINGS OFF}
デフォルト	{$H+} {$LONGSTRINGS ON}
スコープ	ローカル
説明

$H 指令は，予約語 string が型宣言で長さの指定なしで使われるときの意味を制御します。汎用型 string は，動的に割り当てられる長い文字列 (基本型 AnsiString) か，あるいはまたは静的に割り当てられる短い文字列 (基本型 ShortString) のいずれかを表します。

デフォルトの {$H+} では，汎用文字列型は長い AnsiString 型と定義されます。ビジュアルコンポーネントライブラリのすべてのコンポーネントは，この状態でコンパイルされています。コンポーネントを記述するときは，長い文字列を使用する必要があります。VCL の文字列型プロパティからデータを受け取るコードも同様です。

{$H-} 状態は，デフォルトで短い文字列を使用する Object Pascal のバージョンからのコードを使用するのに役立ちます。文字列型定義の意味を部分的にオーバーライドして，短い文字列を確実に生成することができます。また，短い文字列型の宣言を string[255] または ShortString に変更することもできます。これらは意味が明確であり，$H の状態には依存しません。


Memory allocation sizes
Memory allocation sizes1056026

Section topics	参照

種類	パラメータ
構文	{$M minstacksize,maxstacksize} {$MINSTACKSIZE number} {$MAXSTACKSIZE number}
デフォルト	{$M 16384,1048576}
スコープ	グローバル
説明

$M 指令は，アプリケーションのスタック割り当てパラメータを指定します。minstacksize はアプリケーションスタックの最小サイズを指定し，1024～2147483647 の整数でなければならず，maxstacksize はアプリケーションスタックの最大サイズを指定し，minstacksize～2147483647 の整数でなければなりません。

アプリケーションの最小スタック要件を満たす十分なメモリが使用できない場合，Windows はアプリケーションを起動しようとしたときにエラーを報告します。

アプリケーションスタックのサイズは最大スタックサイズを超えてはなりません。最大スタックサイズより大きくしようとすると EStackOverflow 例外が生じます。

$MINSTACKSIZE と $MAXSTACKSIZE 指令を使うと，最小および最大スタックサイズを別々に指定することができます。

メモリ割り当て指令はプログラムにおいてのみ意味があります。ライブラリやユニットでは使用できません。


Minimum enumeration size
Minimum enumeration size1056027

Section topics	参照

種類	パラメータ
構文	{$Z1} または {$Z2} または {$Z4} {$MINENUMSIZE 1} または {$MINENUMSIZE 2} または {$MINENUMSIZE 4}
デフォルト	{$Z1} {$MINENUMSIZE 1}
スコープ	ローカル
説明

$Z 指令は，列挙型の最小記憶域サイズを制御します。

列挙型は，列挙されるのが 256 を超えず，型が {$Z1} 状態 (デフォルト) で宣言されている場合，符号なしのバイトとして格納されます。列挙型が 256 以上あるかまたは {$Z2} 状態で宣言されている場合は，符号なしのワードとして格納されます。最後に，列挙型が {$Z4} 状態で宣言されている場合は，符号なしのダブルワードとして格納されます。

{$Z2} と {$Z4} 状態は，C および C++ ライブラリとのインターフェースに役立ちます。通常これらのライブラリでは，列挙型はワードまたはダブルワードで表されます。

メモ	Delphi の初期バージョンおよび Borland Pascal との下位互換性のために指令 {$Z-} と {$Z+} はどちらもサポートされています。これらの指令は，それぞれ {$Z1} と {$Z4} に対応します。


Open String Parameters
Open String Parameters1056028

Section topics	参照

種類	スイッチ
構文	{$P+} または {$P-} {$OPENSTRINGS ON} または {$OPENSTRINGS OFF}
デフォルト	{$P+} {$OPENSTRINGS ON}
スコープ	ローカル
説明

$P 指令は，{$H-} 状態でコンパイルされたコードに対してだけ有効であり，Delphi の初期バージョンおよび Borland Pascal との下位互換性のために提供されています。$P は，{$H-} 状態で string キーワードを使って宣言された変数パラメータの意味を制御します。{$P-} 状態にすると，string キーワードを使って宣言された変数パラメータは，通常の変数パラメータですが，{$P+} 状態では，オープン文字列パラメータです。$P 指令の設定にかかわらず，OpenString 識別子は常にオープン文字列パラメータの宣言に使用されます。オープンパラメータについての詳細は，『Object Pascal 言語ガイド』の第 9 章を参照してください。


Optimization
Optimization1056029

Section topics	参照

種類	スイッチ
構文	{$O+} または {$O-} {$OPTIMIZATION ON} または {$OPTIMIZATION OFF}
デフォルト	{$O+} {$OPTIMIZATION ON}
スコープ	ローカル
説明

$O 指令は，コードの最適化を制御します。{$O+} 状態にすると，コンパイラは多くのコードの最適化を実行します。たとえば，CPU レジスタへの変数の配置，共通の部分式の削除，導入変数の生成などを行います。{$O-} 状態にすると，このような最適化は行われません。

特定のデバッグ環境以外では，最適化をオフにする必要はありません。Delphi の Object Pascal コンパイラにより実行されるすべての最適化は，プログラムの意味を変更しないことが保証されています。言い換えると，Delphi ではプログラマの特別な注意を必要とするような「安全でない」最適化は行われません。


Overflow checking
Overflow checking1056030

Section topics	参照

種類	スイッチ
構文	{$Q+} または {$Q-} {$OVERFLOWCHECKS ON} または {$OVERFLOWCHECKS OFF}
デフォルト	{$Q-} {$OVERFLOWCHECKS OFF}
スコープ	ローカル
説明

$Q 指令は，オーバーフローチェックコードの生成を制御します。{$Q+} 状態にすると，特定の整数算術演算 (+，-，*，Abs，Sqr，Succ，Pred，Inc，および Dec) のオーバーフローがチェックされます。これらの整数演算のコードには，結果がサポート範囲内であることを検証するコードが追加されます。オーバーフローチェックが検出されると，EIntOverflow 例外が生じます (例外ハンドラが使用できない場合はプログラムが終了します)。

$Q スイッチは，常に $R スイッチとともに使用され，範囲チェックコードの生成を使用可能または使用不可にします。オーバーフローチェックを可能にすると，プログラムの速度が遅くなり，いくらかサイズも大きくなります。したがって，{$Q+} はデバッグ用にのみ使用してください。


Pentium-safe FDIV operations
Pentium-safe FDIV operations1056031

Section topics	参照

種類	スイッチ
構文	{$U+} または {$U-} {$SAFEDIVIDE ON} または {$SAFEDIVIDE OFF}
デフォルト	{$U-}
スコープ	ローカル
説明

$U 指令は，初期の Pentium プロセッサの FDIV 指令の欠陥に対応した浮動小数点コードの生成を制御します。Windows 95，Windows NT 3.51 および 4.0 には，Pentium FDIV のバグをシステムレベルで修正するコードが含まれています。

{$U+} 状態にすると，すべての浮動小数点除算はランタイムライブラリルーチンを使って実行されます。浮動小数点除算ルーチンが初めて呼び出されると，プロセッサの FDIV 命令が正しく機能するかチェックします。そして，TestFDIV 変数 (System ユニットで宣言されている) を適切に更新します。その後の浮動小数点除算では，TestFDIV に格納されている値によって動作が決定されます。

値	意味
�1	FDIV 命令がテストされ，欠陥が検出された
0	FDIV 命令はまだテストされていない
1	FDIV 命令がテストされ，正常であることが検出された
FDIV の欠陥のないプロセッサの場合，{$U+} によりわずかに処理速度が低下します。欠陥のある Pentium プロセッサでは，{$U+} 状態では浮動小数点除算は最大で約 3 倍の時間がかかりますが，常に正しい結果が得られます。

{$U-} 状態にすると，浮動小数点除算はインラインの FDIV 命令を使って実行されます。これにより，最適の速度とコードサイズが得られますが，欠陥のある Pentium プロセッサでは誤った結果が与えられる可能性があります。{$U-} 状態は，コードが欠陥のある Pentium プロセッサ上で実行されないことが確実な場合にだけ使用してください。


Range checking
Range checking1056032

Section topics	参照

種類	スイッチ
構文	{$R+} または {$R-} {$RANGECHECKS ON} または {$RANGECHECKS OFF}
デフォルト	{$R-} {$RANGECHECKS OFF}
スコープ	ローカル
説明

$R 指令は，範囲チェックコードの生成を使用可能または使用不可にします。{$R+} 状態にすると，すべての配列および文字列の添字式が定義された範囲内にあるかどうかが検査されます。また，スカラー型および部分範囲型変数へのすべての代入が範囲内にあるかどうかも検査されます。範囲チェックに失敗すると，ERangeError 例外が生じます (例外ハンドラが使用できない場合はプログラムが終了します)。

範囲チェックを有効にすると，プログラムの速度が低下しサイズも大きくなります。したがって，{$R+} はデバッグ用にのみ使用してください。

メモ	長い文字列は，範囲チェックされません。


Resource file
Resource file1056033

Section topics	参照

種類	パラメータ
構文	{$R Filename} {$RESOURCE filename}
スコープ	ローカル
説明

$R 指令は，アプリケーションやライブラリに含むべきリソースファイルの名前を指定します。指定するファイルは Windows リソースファイルでなければならず，ファイル名のデフォルト拡張子は .RES です。

ユニットで {$R filename} 指令が使用されると，指定したファイル名が結果のユニットファイルに単に記録されます。この時点では，ファイル名が有効で既存のファイルを指定しているかどうかはチェックされません。

アプリケーションまたはライブラリを (コンパイル後に) リンクするときに，プログラムまたはライブラリ自体だけでなく使用するすべてのユニットで指定されているリソースファイルが処理されます。そして，各リソースファイル内のリソースは作成中の実行形式ファイルにコピーされます。リソースの処理段階では，Delphi のリンカは $R 指令を含むモジュールと同じディレクトリ内で .RES ファイルを検索します。また，［プロジェクトオプション］ダイアログボックスの［ディレクトリ/条件］ページの［検索パス(S)］入力ボックスに指定されているディレクトリ (または DCC32 コマンドラインの /R オプションで指定されるディレクトリ) も検索します。


RUNONLY directive
RUNONLY directive1056034

Section topics	参照

種類	スイッチ
構文	{$RUNONLY ON} または {$RUNONLY OFF}
デフォルト	{$RUNONLY OFF}
スコープ	ローカル
説明

{$RUNONLY ON} 指令は，この指令を含むパッケージが実行時だけコンパイルされるようにします。{$RUNONLY ON} によりコンパイルされたパッケージは，Delphi IDE の設計時パッケージにインストールできません。

$RUNONLY 指令は .DPK ファイルだけに記述します。詳細については『Object Pascal 言語ガイド』の第 15 章を参照してください。


Runtime type information
Runtime type information1056035

Section topics	参照

種類	スイッチ
構文	{$M+} または {$M-} {$TYPEINFO ON} または {$TYPEINFO OFF}
デフォルト	{$M-} {$TYPEINFO OFF}
スコープ	ローカル
説明

$M スイッチ指令は，実行時型情報 (RTTI) の生成を制御します。クラスが {$M+} 状態で宣言されるとき，または {$M+} 状態で宣言されたクラスから派生するとき，コンパイラは published セクションで宣言されているフィールド，メソッド，プロパティの実行時型情報を生成します。クラスが {$M-} 状態で宣言されていて，{$M+} 状態で宣言されたクラスからの派生クラスではない場合，published セクションはそのクラスで使用できません。

メモ	Delphi ビジュアルクラスライブラリの Classes ユニットに定義される TPersistent クラスは {$M+} 状態で宣言されており，TPersistent から派生するクラスには，published セクションに対して生成された RTTI が含まれます。Delphi ビジュアルコンポーネントライブラリは，published セクションに対して生成された 実行時型情報を使用して，ファイルからの読み込みを保存するときにコンポーネントのプロパティの値にアクセスします。さらに，Delphi IDE は，コンポーネントの実行時型情報を使って，オブジェクトインスペクタに表示するプロパティのリストを決定します。

アプリケーションが直接 $M コンパイラスイッチを使う必要はめったにありません。


Symbol cross-reference information
Symbol cross-reference information1056036

Section topics	参照

種類	スイッチ
構文	{$Y+} または {$Y-} {$REFERENCEINFO ON} または {$REFERENCEINFO OFF}
デフォルト	{$Y+} {$REFERENCEINFO ON}
スコープ	グローバル
説明

$Y 指令は，シンボル参照情報の生成をオンまたはオフにします。この情報には，モジュール内のシンボルの宣言と参照の行番号を提供するテーブルが含まれています。

ユニットの場合，シンボル参照情報は，ユニットのオブジェクトコードとともに .DCU ファイルに記録されます。シンボル参照情報を生成することによって .DCU ファイルのサイズは増加しますが，実行形式プログラムのサイズや速度には影響しません。

プログラムまたはユニットを {$Y+} 状態でコンパイルすると，Delphi IDE のブラウザは，そのモジュールのシンボル定義と参照情報を表示することができます。

$Y スイッチは，通常 $D および $L スイッチとともに使用します。これらは，デバッグ情報とローカルシンボル情報の生成を制御します。$D および $L スイッチが無効の場合は $Y 指令も無効です。

メモ	シンボル参照情報の生成を行うとコンパイル/リンク速度がかなり落ちます。したがって，オブジェクトブラウザを使用する必要がなければ，このスイッチはオフにしておきます。


Type-checked pointers
Type-checked pointers1056037

Section topics	参照

種類	スイッチ
構文	{$T+} または {$T-} {$TYPEDADDRESS ON} または {$TYPEDADDRESS OFF}
デフォルト	{$T-} {$TYPEDADDRESS OFF}
スコープ	グローバル
説明

$T 指令は，@ 演算子により生成されるポインタ値の型を制御します。{$T-} 状態にすると，@ 演算子の結果型は，常にほかのすべてのポインタ型と互換性のある型なしポインタです。{$T+} 状態で @ を変数の参照に適用すると，結果の型は ^T になります。このとき T は，変数の型についてだけほかのポインタと互換性があります。


UNDEF directive
UNDEF directive1056038

Section topics	参照

種類	条件コンパイル
構文	{$UNDEF name}
説明

前に定義した条件シンボルの定義を解除します。シンボルは，現在のソースファイルのコンパイルの残りの間，または {$DEFINE name} 指令で再び指定されるまで未定義になります。{$UNDEF name} 指令は，nameが未定義の場合には無効です。

コマンドラインスイッチまたは IDE の［プロジェクトオプション］ダイアログで定義される条件シンボルは，各ユニットソースファイルのコンパイルの開始時に再び定義されます。逆に，ユニットソースファイルで定義された条件シンボルは，コンパイラが別のユニットの処理を開始した時点で未定義になります。


Var-string checking
Var-string checking1056039

Section topics	参照

種類	スイッチ
構文	{$V+} または {$V-} {$VARSTRINGCHECKS ON} または {$VARSTRINGCHECKS OFF}
デフォルト	{$V+} {$VARSTRINGCHECKS ON}
スコープ	ローカル
説明

$V 指令は，短い文字列を使用するコードに対してだけ意味があり (LONGSTRINGS 指令参照)，Delphi の初期バージョンおよび Borland Pascal との下位互換性を提供します。

$V 指令は，変数パラメータとして渡された短い文字列の型チェックを制御します。{$V+} 状態にすると，厳密な型チェックが行われ，仮パラメータと実パラメータが同一の文字列型であることを要求します。{$V-} 状態 (緩い型チェック) では，短い文字列型の変数はすべて実パラメータとして使用できます。宣言された最大長が仮パラメータの最大長と同じでなくてもかまいません。


Warnings
Warnings1056040

Section topics	参照

種類	スイッチ
構文	{$WARNINGS ON} or {$WARNINGS OFF}
デフォルト	{$WARNINGS ON}
スコープ	ローカル
説明

$WARNINGS 指令は，コンパイラ警告の生成を制御します。

{$WARNINGS ON} 状態では，コンパイラは，初期化されていない変数，関数結果の欠落，抽象オブジェクトのインスタンス作成などを検出したときに警告メッセージを出力します。{$WARNINGS OFF} 状態では，コンパイラは警告メッセージを生成しません。

{$WARNINGS OFF} と {$WARNINGS ON} 指令の間にコードを記述すると，不要な警告をオフにすることができます。


Weak packaging
Weak packaging1056041

Section topics	参照

種類	スイッチ
構文	{$WEAKPACKAGEUNIT ON} または {$WEAKPACKAGEUNIT OFF}
デフォルト	{$WEAKPACKAGEUNIT OFF}
スコープ	ローカル
説明

$WEAKPACKAGEUNIT 指令は，.DCU ファイルがパッケージの .DCP および .DPL ファイルに格納される方法に影響します。{$WEAKPACKAGEUNIT ON} がユニットファイルに記述されていると，コンパイラは可能であればそのユニットを DPL から外します。そして，別のアプリケーションやパッケージがそのユニットを必要とした場合には，ユニットの非パッケージローカルコピーを作成します。この指令によりコンパイルされたユニットは「弱くパッケージ化されている (weakly packaged)」と呼びます。

たとえば，UNIT1 というユニットだけを含む PACK というパッケージがあるとします。UNIT1 はほかにユニットを使用しませんが，RARE.DLL を呼び出すものとします。コンパイルの前に {$WEAKPACKAGEUNIT ON} 指令が UNIT1.PAS に挿入されると，UNIT1 は PACK.DPL に含まれません。RARE.DLL のコピーを PACK に配布する必要はありません。しかし，UNIT1 は依然として PACK.DCP に含まれています。UNIT1 は，PACK を使用する別のパッケージまたはアプリケーションに参照されると，PACK.DCP からコピーされて直接プロジェクトにコンパイルされます。

ここで，2 番目のユニット UNIT2 が PACK に追加されたとします。UNIT2 は UNIT1 を使用します。今度は，PACK が UNIT1.PAS で {$WEAKPACKAGEUNIT ON} によりコンパイルされていたとしても，コンパイラは UNIT1 を PACK.DPL に含めます。ただし，UNIT1 を参照するほかのパッケージやアプリケーションは，やはり PACK.DCP からコピーされた (非パッケージの) コピーを使用します。

メモ	{$WEAKPACKAGEUNIT ON} 指令を含むユニットファイルには，グローバル変数，初期化部，または終了処理部が含まれてはなりません。

$WEAKPACKAGEUNIT 指令は，DPL をほかの Delphi プログラマに配布する開発者のための拡張機能です。めったに使用されることのない DLL の配布を避け，同じ外部ライブラリに依存しているパッケージ間の競合をなくす一助になります。

たとえば，Delphi のPenWin ユニットは PENWIN.DLL を参照します。ほとんどのプロジェクトは PenWin を使用しません。また，ほとんどのコンピュータには PENWIN.DLL がインストールされていません。したがって，PenWin ユニットは VCL30 (Delphi のコンポーネントが一般的に使用する多くのパッケージがカプセル化されている) の弱いパッケージといえます。PenWin と VCL30 パッケージを使用するプロジェクトをコンパイルすると，PenWin は VCL30.DCP からコピーされて直接プロジェクトに結び付けられます。その結果，実行可能ファイルは静的に PENWIN.DLL にリンクされます。

PenWin が弱いパッケージでなかったとすると，2 つの問題が生じます。第 1 に，VCL30 自体が静的に PENWIN.DLL にリンクされ，PENWIN.DLL がインストールされていないコンピュータでは読み込みできなくなります。第 2 に，誰かが PenWin を含むパッケージを作成しようとすると，PenWin ユニットが VCL30 と新規パッケージの両方に含まれることになるためコンパイラエラーが発生します。したがって，弱いパッケージを使わなければ，PenWin を VCL30 の標準配布に含めることはできません。


Windows stack frames
Windows stack frames1056042

Section topics	参照

種類	スイッチ
構文	{$W+} または {$W-} {$STACKFRAMES ON} または {$STACKFRAMES OFF}
デフォルト	{$W-} {$STACKFRAMES OFF}
スコープ	ローカル
説明

$W 指令は，手続きと関数のスタックフレームの生成を制御します。{$W+} 状態にすると，スタックフレームは不必要な場合でも常に手続きと関数のために生成されます。{$W-} 状態では，スタックフレームはローカル変数のルーチンを使用して決定されるように，必要な場合にだけ生成されます。

デバッグツールの中には，すべての手続きと関数のためにスタックフレームの生成を必要とするものもありますが，それ以外には {$W+} 状態での使用を必要とすることはないでしょう。


Writeable typed constants
Writeable typed constants1056043

Section topics	参照

種類	スイッチ
構文	{$J+} または {$J-} {$WRITEABLECONST ON} または {$WRITEABLECONST OFF}
デフォルト	{$J+} {$WRITEABLECONST ON}
スコープ	ローカル
説明

$J 指令は，型付き定数が変更できるかどうかを制御します。{$J+} 状態にすると型付き定数は変更でき，実質的にはこれらは初期化済み変数です。{$J-} 状態では，型付き定数は真に定数であり，これを変更しようとすると，コンパイラはエラーを報告します。

初期バージョンの Delphi および Borland Pascal では，型付き定数は常に書き込み可能で， {$J+} 状態に対応していました。書き込み可能な型付き定数を使う古いソースコードは {$J+} 状態でコンパイルしなければなりません。ただし，新しいアプリケーションでは初期化済み変数を使うようにし，コードは {$J-} 状態でコンパイルすることをお勧めします。


Using conditional compilation directives
Using conditional compilation directives1056044

Section topics	参照

2 つの基本的な条件コンパイル構文は，Pascalの if 文に似ています。最初の構文は次のとおりです。

{$IFxxx}

   ...

{$ENDIF}

この構文は，{$IFxxx} と {$ENDIF} の間のソーステキストを {$IFxxx} で指定した条件が真の場合にだけコンパイルします。条件が偽の場合には，2 つの指令の間のソーステキストは無視されます。

2番目の条件コンパイル構文は次のとおりです。

{$IFxxx}

   ...

{$ELSE}

   ...

{$ENDIF}

これは，{$IFxxx} と {$ELSE} の間のソーステキスト，または {$ELSE} と {$ENDIF} 間のソーステキストのいずれかを，{$IFxxx} で指定した条件によってコンパイルします。

以下にいくつかの条件コンパイル構文の例を示します。

{$IFDEF Debug}

  Writeln('X = ', X);

{$ENDIF}

{$IFDEF WIN32}

  P := SmallPointToPoint(Message.Pos);

{$ELSE}

  P := Message.Pos;

{$ENDIF}

条件コンパイル構文は，最大 16 レベルまでネストできます。各 {$IFxxx} ごとに，対応する {$ENDIF} が同じソースファイル内に記述されていなければなりません。これは，すべてのソースファイルでは，{$IFxxx} と {$ENDIF} の数が同じであることを意味します。


Conditional symbols
Conditional symbols1056045

Section topics	参照

条件コンパイルは，条件シンボルの評価を基にしています。条件シンボルは，次の指令を使って定義または定義解除されます。

{$DEFINE name}

{$UNDEF name}

コマンドラインコンパイラの /D スイッチを使って，シンボルを定義することもできます (またはIDE の［プロジェクトオプション］ダイアログボックスの［ディレクトリ/条件］ページの［条件定義(C)］入力ボックスにシンボルを追加します)。

条件シンボルは論理変数と比較するとよくわかります。つまり，条件シンボルは True (定義済み) または False (未定義) のいずれかになります。{$DEFINE} 指令は，指定したシンボルを True に設定し，{$UNDEF} 指令は False に設定します。

条件シンボルは，Pascal 識別子と同じ規則に従います。すなわち，英字で始まり，任意の文字，数字，下線記号が続きます。長さは任意ですが，最初の 255 文字までが有効です。

条件シンボルと Pascal 識別子の間には何の関係もありません。条件シンボルは実際のプログラムで参照することはできません。また，プログラムの識別子を条件指令で参照することもできません。たとえば，次のような構文があるとします。

const

  Debug = True;

begin

  {$IFDEF Debug}

  Writeln('Debug is on');

  {$ENDIF}

end;

これは，Writeln 文をコンパイルしません。次も同様です。

{$DEFINE Debug}

begin

  if Debug then

    Writeln('Debug is on');

end;

これも，if 文で未知の識別子エラーとなります。

Delphi では，次の標準条件シンボルを定義しています。

VER100	常に定義される。Object Pascal コンパイラのバージョンが 10.0 であることを示す。各バージョンは定義済みのシンボルに対応する。たとえば，バージョン 10.1 では VER101 と定義され，バージョン 10.5 では VER105 というように定義される
WIN32	Delphi 3 では常に定義される。操作環境が Win32 API であることを示す
CPU386	Delphi 3 では常に定義される。CPU が Intel 386 またはその上位プロセッサであることを示す
CONSOLE	アプリケーションがコンソールアプリケーションとしてコンパイルされるときに定義される

［条件定義(C)］入力ボックスまたは /D コマンドラインオプション (コマンドラインコンパイラを使用している場合) を使うと，コンパイル前にそのほかの条件シンボルも定義できます。

メモ	ソースコードの条件定義は，そのソースファイルが再コンパイルされるときにだけ評価されます。前述のように，条件定義の変更してプロジェクトを再コンパイル (メイク) した場合，ユニットはソースから再コンパイルされません。したがって，ユニットには条件定義の変更が反映されません。条件定義の変更をプロジェクト内のすべてに確実に反映させるには［再構築(B)］を使用します。


See also1056046

コマンドラインコンパイラ


Making effective use of the development environment
Making effective use of the development environment1086001

Section topics 	参照

Delphi の開発環境には，データベースアプリケーション開発者にとって特に有用なツールとコンポーネントが用意されています。オブジェクトリポジトリやデータモジュールなどのように Delphi で一般的に使うものもあれば，データベース／SQL エクスプローラやクライアントデータセットコンポーネントなどのようにデータベース開発専用に使うものもあります。以降の各節では，Delphi のこれらの機能に焦点を当てて説明します。各機能について詳細を知りたい場合の参照先も示します。

この章では，Delphi のデータベースアーキテクチャについても説明します。Delphi のオープンデータベースアーキテクチャの概要図のほか，Delphi を使って作成できるデータベースアプリケーションの種類ごとの構造図を示します。単一層，2 層，多層の各アプリケーションで使う場合の Delphi データベースコンポーネントの関係も図で示します。

Delphi のデータベース機能とデータベースツールは，さまざまなコンピューティング環境でのデータベースアプリケーションの設計，実装，配布，保守を簡単にします。

SQL エクスプローラ，SQL モニタ，クライアントデータセット，リモートデータモジュール，プロバイダコンポーネントなどの Delphi のデータベース機能とデータベースツールは Delphi Client/Server Suite に固有のものです（Delphi Professional および Delphi Standard では SQL エクスプローラのかわりにデータベースエクスプローラを使います）。標準データベースコンポーネント，BDE，スタンドアロン Database Desktop（DBD）などのツールは Delphi のすべての版で提供されています。

一般に，Delphi Client/Server Suite は，リモートサーバー上の SQL データベースに加え，ネットワーク上およびローカルの Paradox，dBASE，MS Access，FoxPro の各データベースとも動作する 2 層または多層のアプリケーションの構築，テスト，配布に必要なツールと機能を完備しています。サードパーティの ODBC ドライバを使えば，ODBC 準拠のローカルおよびリモートのデータベースにもアクセスできます。

Delphi Professional ではネットワーク上およびローカルの Paradox，dBASE，Access，FoxPro の各データベース用のクライアントアプリケーションの構築およびテストが可能です。サードパーティの ODBC ドライバを使えば，ODBC 準拠のローカルおよびリモートのデータベースにもアクセスできます。

Delphi Standard ではネットワーク上およびローカルの Paradox，dBASE，Access，FoxPro の各データベース用のクライアントアプリケーションの構築およびテストが可能です。


Browsing and designing with the SQL Explorer
Browsing and designing with the SQL Explorer1086002

Section topics 	参照

Delphi Client/Server Suite では，IDE の SQL エクスプローラを使ってデータベースをブラウズしテーブルにデータを取り込みます。Delphi Professional ではデータベースエクスプローラを使います。どちらのエクスプローラでも以下のようなことができます。

既存のデータベーステーブルと構造の検査。SQL エクスプローラを使うと，リモート SQL データベースの検査や問い合わせができる

SQL エクスプローラを使ったリモートデータベースサーバー上での SQL オブジェクト（ストアドプロシージャなど）の作成。サーバー上での SQL オブジェクトを再構成したテキストを表示することもできる

SQL エクスプローラでの SQL スクリプトの実行

テーブルへのデータの取り込み

後での取り出しおよび再利用に備えたデータディクショナリへの拡張項目属性セットの作成。拡張項目属性は項目の値がどのように形式化されて表示されるかを記述する

拡張項目属性とアプリケーションの項目の関連付け

アプリケーションによってデータベースへの接続に使われる BDE エリアスの作成と管理

SQL エクスプローラとデータベースエクスプローラについての詳細は，それぞれのオンラインヘルプファイルを参照してください。


Using the Data Dictionary
Using the Data Dictionary1086003

Section topics

データディクショナリはカスタマイズ可能な格納領域をアプリケーションとは別に提供するもので，データの外観および内容を記述する拡張項目属性セットの作成が可能になります。

たとえば，頻繁に財務アプリケーションを開発する場合は，各種の通貨表示形式を記述する特殊な項目属性セットを数多く作成する可能性があります。設計時に開発アプリケーションのデータセットを作成する場合は，オブジェクトインスペクタを使って各データセットに通貨型項目を手作業で設定するのではなく，データディクショナリに設定されている拡張項目属性セットに通貨型項目を関連付けられます。またデータディクショナリを使うと，作成するアプリケーション内およびそのアプリケーション全体でデータの外観が一貫したものになります。

クライアント／サーバー環境では，データディクショナリをリモートサーバーに置いて一層の情報共有に備えることができます。

設計時に項目エディタで拡張項目属性セットを作成する方法，およびアプリケーションのデータセットを通してそれらの属性セットを項目に関連付ける方法については，「項目コンポーネントの操作」を参照してください。SQL エクスプローラおよびデータベースエクスプローラを使ったデータディクショナリおよび拡張項目属性の作成についての詳細は，それぞれのオンラインヘルプファイルを参照してください。


Creating multi-tiered database applications
Creating multi-tiered database applications1086004

Section topics 	参照

新しい Delphi データベースコンポーネントを使えば，多層データベースアプリケーションを作成できます。

TClientDataset を使えば，ローカルのデータソースやファイルおよびリモートアプリケーションサーバーからデータを取り出せる，データベースエンジンに依存しないデータセットを作成できます。ボーランドデータベースエンジン（BDE）を使わない単一層データベースアプリケーションも作成できます。クライアントアプリケーションで TClientDataSet コンポーネントを多層データベースアプリケーションの一部として使うこともできます。TClientDataSet についての詳細は「クライアントデータセットの作成と使い方」を参照してください。

TRemoteServer を使えば，DCOM を使ってリモートアプリケーションサーバーに接続するクライアントアプリケーションを作成できます。TRemoteServer の使い方についての詳細は「多層アプリケーションの作成」を参照してください。

TProvider を使えば，クライアントアプリケーションとアプリケーションサーバー間にデュアルインターフェースを作成できます（TProvider コンポーネントはアプリケーションサーバー上にあります）。これにより，クライアントアプリケーションのクライアントデータセットがプロバイダを通じて，または直接にアプリケーションサーバー上のデータセットと通信できます。


Designing a database interface with data-aware controls
Designing a database interface with data-aware controls1086005

Section topics 	参照

データモジュールにデータベースアクセスコンポーネントを追加することで，一貫したユーザーインターフェースにのみ関連するフォームをデータベースアプリケーション内で開発できます。TDBGrid コントロール，TDBLookupListBox および TDBLookupComboBox コントロール，複数のデータ項目をマルチレコードで表示できる TDBCtrlGrid コントロールなどの各拡張機能を使うと，アプリケーションのユーザーインターフェースはさらに強力で効果的なものになります。

適切に設計されたフォームおよびデータモジュールへのリンクをオブジェクトリポジトリに格納することによって，新規プロジェクトごとに最初から開発を始めるのではなく，既存の土台に基づいて開発することが可能になります。フォームやモジュールを共有することで，データベースアクセスやアプリケーションインターフェースの社内標準を開発することもできます。

データコントロールの操作についての詳細は「データコントロールの使い方」を参照してください。グリッドの使い方についての詳細は「グリッドの操作」を参照してください。


Using the Database Desktop with Paradox and dBASE files
Using the Database Desktop with Paradox and dBASE files1086006

Section topics 	参照

Database Desktop（DBD）を使えば，既存の Paradox テーブルおよび dBASE テーブルのブラウズと変更，新規テーブルの作成とそのテーブルへのデータの取り込み，インデックスの作成，参照の整合性の定義，テーブルに対するデータベースレベルでの検証およびビジネスルールの作成が可能になります。BDE エリアスの作成やブラウズも可能です。

DBD は Delphi IDE の外部で実行されるスタンドアロンユーティリティです。DBD についての詳細は，オンラインヘルプを参照してください。


Using data modules and remote data modules
Using data modules and remote data modules1086007

Section topics 	参照

データモジュールは，アプリケーションでのデータアクセス開発を大幅に軽減します。データモジュールはすべてのデータアクセスコンポーネント用の一元化コンテナを用意してコードのモジュール化を可能にします。さらに，アプリケーション内のデータベースアクセスロジックやビジネスルールを，アプリケーションフォームのユーザーインターフェースロジックと分離します。

データセットとその項目をデータモジュールにいったん定義すると，そのモジュールを使うすべてのフォームが一貫してデータセットおよび項目にアクセスします。したがって，必要なたびごとに各フォーム上にそれらのデータセットや項目を再作成する必要がありません。データモジュールは開発者間およびアプリケーション間での共有利用のためにオブジェクトリポジトリに格納でき，またそうすべきものです。

Delphi 3.0 の新機能であるリモートデータモジュールを使えば，ActiveX データモジュールを作成できます。ActiveX データモジュールは，多層のクライアント／サーバーデータベースアプリケーション内でアプリケーションサーバーとして機能できる OLE 対応オートメーションオブジェクトを作成するときの土台になります。

データモジュールについての詳細は，『ユーザーズガイド』を参照してください。リモートデータモジュールを使って多層データベースアプリケーション用のアプリケーションサーバーを作成する方法についての詳細は，「多層アプリケーションの作成」を参照してください。


Creating and using component templates
Creating and using component templates1086008

Section topics 	参照

Delphi 3.0 ではコンポーネントテンプレートが導入されています。コンポーネントテンプレートを使えば，フォーム上にグループ化したコンポーネントをいくつでも設定でき，さらにそれらのコンポーネントのプロパティの設定とイベントハンドラの作成ができます。結果として得られたコンポーネントグループは，後で再利用できるようにコンポーネントパレットに格納できます。デフォルトの動作でカスタムインターフェースのレイアウト作成や設計を行い，その内容をすべての社内アプリケーション間で矛盾のないように実現する場合に，コンポーネントテンプレートを使うと便利です。

コンポーネントテンプレートの作成と使い方についての詳細は，『ユーザーズガイド』を参照してください。


Using the Object Repository
Using the Object Repository1086009

Section topics 	参照

オブジェクトリポジトリはデータモジュール，フォーム，プロジェクトへのリンクを格納して再利用と参照に備えます。新規アプリケーションを作成するときは，以下の 3 通りの方法が可能です。

既存のデータモジュール，フォーム，プロジェクトをコピーする方法。コピーはリポジトリとはまったく関係なくなる

既存のデータモジュール，フォーム，プロジェクトを継承する方法。リポジトリ内のリンクしたモジュール，フォーム，プロジェクトへの変更内容は再コンパイル時にアプリケーションへ複製される

既存のデータモジュール，フォーム，プロジェクトをそのまま利用する方法。そのモジュール，フォーム，プロジェクトへの変更内容はほかのアプリケーションで利用が可能である

オブジェクトリポジトリはチーム開発に役立ちます。ネットワークサーバー上または共有マシン上のデータモジュール，フォーム，プロジェクトを参照する方法を使っています。組織内の各開発者はオブジェクトをその共有場所に保存して，Delphi のオブジェクトリポジトリ参照がその場所を指すように設定できます。

オブジェクトリポジトリは IDE の［ツール(T)｜リポジトリ(R)］によってカスタマイズも可能です。

Delphi プログラミング全般でのオブジェクトリポジトリの使い方についての概要は，『ユーザーズガイド』を参照してください。


Overview of Delphi's database architecture
Overview of Delphi's database architecture1086010

Section topics 	参照

Delphi の新しいオープンデータベースアーキテクチャは，利用可能なすべてのデータベースエンジンでデータベースアプリケーションを作成できます。新規に組み込まれたクライアントデータセットコンポーネントを使えばボーランドデータベースエンジン（BDE）を使う必要がなくなります。また，既存のすべての Delphi データセットコンポーネントの基礎となっている，データベースに依存しない汎用の TDataSet コンポーネントからカスタムデータセットコンポーネントを派生させても，BDE を使う必要がなくなります。Delphi のどの版を使うかにより，以下のアプリケーションを作成できます。

BDE を通じて動作し，ローカルの Paradox ファイルや dBASE ファイルにアクセスする単一層データベースアプリケーション

フラットデータファイルで直接データを読み書きする単一層データベースアプリケーション

ローカルまたはリモートのデータベースサーバーと対話する 2 層のクライアント／サーバークライアントアプリケーション

多層の分割されたクライアント／サーバーアプリケーション。クライアントアプリケーションはユーザーインターフェースを提供し，通常は別のマシン上にあるアプリケーションサーバー（リモートデータブローカーともいいます）と対話する。アプリケーションサーバーはリモートデータベースサーバーと対話する

これらの開発モデルはどれも Delphi の新しいオープンデータセットアーキテクチャを利用しています。図に，このオープンデータセットアーキテクチャの概要を示します。

Delphi's open dataset architecture1086011

図に示すように，Delphi では何通りかの方法でデータベースアプリケーションを構築できます。従来通り，既製の BDE 対応データベースコンポーネントが各種用意されているので，これらのコンポーネントを使って複雑で高度なデータベースアプリケーションを短時間で簡単に作成できます。単純な単一層データベースアプリケーションを作成する場合や，必要なときだけ BDE を使う複雑な多層データベースソリューションを開発する場合，Delphi Client/Server Suite の新規コンポーネント TClientDataSet を使えます。BDE のかわりにサードパーティまたは独自のデータベースエンジンを使う場合は，TDataSet からカスタムデータセットコンポーネントを派生させることができます。

以降の各節では，これらのモデルのそれぞれについて詳しく説明します。構築するデータベースアプリケーションの種類ごとに，ユーザーインターフェースに共通の Delphi 要素についても説明します。


Understanding the user interface
Understanding the user interface1086012

Section topics 	参照

Delphi には，すべての種類の Delphi データベースアプリケーションのデータへのユーザーインターフェース（UI）を提供する一連のデータベース対応コントロールがあります。データベース対応コントロールではデータベースレコードの項目内のデータが表示されます。ユーザーはそのデータを編集し，その変更内容をデータベースに再度登録できます。データベース対応コントロールは，ユーザーから見たりアクセスしたりできるように，Delphi フォームに置かれます。

これらのコントロールのほとんどは，フォームに配置する標準の Windows コントロールと外観や機能が似ています。たとえば TDBEdit コントロールは，ユーザーがテキスト文字列の表示や編集に使う標準の TEdit コントロールのデータベース対応版です。TDBNavigator や TDBGrid などのデータベース対応コントロールはデータベースのニーズに適した外観と機能を備えています。たとえばナビゲータコントロールでは，データの表示や編集はできませんが，ユーザーはレコードのスクロール，編集モードや挿入モードの開始，レコードの削除，変更内容のデータベースへの登録，更新データの再表示の要求などが可能です。TDBGrid はいくつものレコードの一部またはすべての項目を，表計算ワークシートのような表形式で一度に表示できます。表に，［Data Controls］ページにあるデータベース対応ビジュアルコントロールの概要を示します。

コンポーネント	用途
TDBCheckBox	チェックボックスに論理型項目の条件を表示して設定する
TDBComboBox	項目での編集および入力用に選択肢の編集ボックスおよびドロップダウンリストを表示する
TDBCtrlGrid	（Delphi Client/Server Suite および Professional のみ）レコードを表グリッドで表示して編集する（グリッド内の各セルにはデータベース対応コンポーネントの繰り返しセットと 1 つのレコードが含まれる）。「グリッドの操作」を参照
TDBEdit	編集ボックスに項目を表示して編集する
TDBGrid	データセットレコードを表形式で表示して編集する。「グリッドの操作」を参照
TDBImage	グラフィックイメージやバイナリ BLOB データを表示して編集する
TDBListBox	項目への入力用に選択肢のリストを表示する
TDBLookupComboBox	項目での入力および編集用に別のデータセットの項目から派生した選択肢の編集ボックスおよびドロップダウンリストを表示する
TDBLookupListBox	項目への入力用に別のデータセットの項目から派生した選択肢のリストを表示する
TDBMemo	スクロール可能な複数行の編集ボックスに複数行または BLOB のテキストを表示して編集する
TDBNavigator	データセットレコード間でカーソルを移動する。編集モードや挿入モードの開始，新規レコードや更新レコードの登録，編集モードの取り消し，更新データの再表示を行う。「データコントロールの使い方」を参照
TDBRadioGroup	ラジオボタングループに項目の排他的選択肢を表示して設定する
TDBRichEdit	スクロール可能な複数行の編集ボックスに複数行または BLOB の書式付きテキストを表示して編集する
TDBText	項目をラベルとして表示する
データベース対応コントロールはデータソースコンポーネント TDataSource とデータをやりとりします。データソースコンポーネントはユーザーインターフェースとデータセットコンポーネント（データベーステーブル，問い合わせ，ストアドプロシージャのいずれかを表します）との間の仲介として機能します。フォーム上のいくつかのデータベース対応コントロールは 1 つのデータソースを共有できます。この場合，ユーザーがレコードをスクロールすると現在のレコードの項目の対応する値が各コントロール内に表示されるように，各コントロールでの表示が同期化されます。アプリケーションのデータソースコンポーネントは通常はデータモジュールにあり，フォーム上のデータベース対応コントロールとは切り離されています。

アプリケーションのデータソースコンポーネントはそれぞれ 1 つのデータセットコンポーネントに関連付けられています。データセットコンポーネントは必ず TDataSet から派生します。BDE を使う従来の 2 層クライアントアプリケーションを構築する場合，アプリケーションは TDataSet の下位コンポーネントである TQuery，TStoredProc，TTable を使います。多層の ActiveX 対応データベースアプリケーションを構築する場合，アプリケーションのクライアント部分は新しい TClientDataSet コンポーネントを使えます。このコンポーネントは特定のデータベースエンジンに依存せずにデータセットを表現したものです。カスタムデータセットの下位コンポーネントを派生させて，自分のまたは別のサードパーティのデータベースと対話するのに使うこともできます。どの種類のデータコンポーネントを使うかに関係なく，UI を同じ方法で構築できます。図に，データベースアプリケーションで UI を提供するコンポーネントと，このコンポーネントがデータを取り出し更新データを返すデータセットとの関係を示します。

表に，［Data Access］ページにあるすべてのデータベースコンポーネント（データセットコンポーネントを含みます）の概要と，その詳細の参照先を示します。

コンポーネント	用途
TBatchMove	テーブル間でまとめてデータを移動するために使われるデータセットをカプセル化する。TBatchMove の詳細は「データ構造とテーブル構造のコピー」を参照
TClientDataSet	単一層アプリケーションおよびクライアント上の多層アプリケーションで使える，BDE に依存しないデータセットをカプセル化する。Delphi Client/Server Suite だけで使える。TClientDataSet の詳細は「クライアントデータセットの作成と使い方」を参照
TDataSource	ほかのデータアクセスコンポーネントとデータベース対応ビジュアルコントロールの間の仲介として機能する。TDataSource の詳細は「データソースの操作」を参照
TDatabase	1 つのセッション内の単一のデータベースへのクライアント／サーバー接続をカプセル化する。TDatabase の詳細は「データベースへの接続」を参照
TProvider	多層アプリケーション内でアプリケーションサーバーとクライアントアプリケーションの間の通信チャネルとして機能する ActiveX 対応デュアルインターフェースを提供する。Delphi Client/Server Suite だけで使える。Tprovider の詳細は「多層アプリケーションの作成」を参照
TQuery	SQL 問い合わせに基づいて 1 つまたは複数のローカルまたはリモートのデータベーステーブルから列やレコードの一部を取り出すデータセット。TQuery の詳細は「問い合わせの操作」を参照
TRemoteServer	多層アプリケーション内でクライアントアプリケーションをアプリケーションサーバーに接続する。Delphi Client/Server Suite だけで使える。TRemoteServer の詳細は「多層アプリケーションの作成」を参照
TSession	マルチスレッドデータベースアプリケーション内での単一セッション。特定のデータベースに関連したスレッドそれぞれに独自のセッションがある限り，各セッションは複数のデータベース接続を持つことができる。TSession の詳細は「データベースセッションの管理」を参照
TStoredProc	データベースサーバー用に定義されたストアドプロシージャに基づきデータベーステーブルから 1 つまたは複数のレコードを取り出すデータセット。TstoredProc の詳細は「ストアドプロシージャの操作」を参照
TTable	データベーステーブルからすべての列とレコードを取り出すデータセット。TTable の詳細は「テーブルの操作」を参照
TUpdateSQL	いくつかの問い合わせの読み出し専用結果セットの更新に使える INSERT，UPDATE，DELETE の各 SQL 文。TUpdateSQL の詳細は「キャッシュアップデートの操作」を参照
これらのデータアクセスコンポーネントやデータベース対応コントロールのほかに，Delphi Client/Server Suite のコンポーネントパレットには［Decision Cube］ページがあります。［Decision Cube］ページには，データの分析やクロス集計に使う 6 個のコンポーネントがあります。［Decision Cube］ページのコンポーネントの使い方についての詳細は，デシジョンキューブコンポーネント と「デシジョンコンポーネントの使い方」を参照してください。


Understanding the architecture of a single-tiered BDE application
Understanding the architecture of a single-tiered BDE application1086013

Section topics 	参照

BDE を使って Paradox や dBASE にアクセスする単一層データベースモデルの場合，1 つのアプリケーションにユーザーインターフェースがあり，BDE が組み込まれています。Delphi の従来のバージョンでは，必ずこの種の単一層データベースアプリケーションを作成できるようになっていました。図に，BDE を使う単一層アプリケーションのアーキテクチャモデルを示します。

Single-tiered, BDE-enabled database application architecture1086014

この単一層モデルのほかに，Delphi では BDE をアプリケーションに組み込まなくてもよい新しい単一層モデルをサポートするようになりました。次の節ではこの新しい単一層モデルについて詳細に説明します。


Understanding the architecture of the new, single-tiered application
Understanding the architecture of the new, single-tiered application1086015

Section topics 	参照

Delphi の新しい単一層データベースモデルでは，1 つのアプリケーションにユーザーインターフェースがあります。このモデルでは TClientDataSet コンポーネントを使って，別のデータベースエンジンまたはデータベースサーバーがなくてもディスク上のフラットファイルでデータを読み書きできる，データベースエンジンに依存しないデータセットを作成します。図 2.4 に，クライアントデータセットを使う単一層アプリケーションのアーキテクチャモデルを示します。

Single-tiered database application architecture1086016

TClientDataSet の 2 つのメソッド LoadFromFile と SaveToFile を使うと，クライアントデータセットはフラットファイルから表示用にデータを直接読み出したり，データベース対応コントロールのデータをフラットファイルに直接書き込んだりできます。アプリケーションにデータベースエンジンがなくてもクライアントデータセットコンポーネントがデータベースエンジンのかわりをするといえます。クライアントデータセット用に定義された項目の構造により，ディスクでデータを読み書きする方法が決まります。TClientDataSet を使った単一層データベースアプリケーションの作成についての詳細は「クライアントデータセットの作成と使い方」を参照してください。

メモ	TClientDataSet は，方法は多少異なりますが，多層データベースアプリケーションのクライアント部分でも使われます。Delphi で多層データベースアプリケーションを構築する方法についての概要は「多層アプリケーションの作成」を参照してください。


Understanding the architecture of a two-tiered application
Understanding the architecture of a two-tiered application1086017

Section topics 	参照

2 層データベースモデルの場合，クライアントアプリケーションがデータへのユーザーインターフェースを提供し，BDE を通じてローカルまたはリモートのデータベースサーバーと直接対話します。

次の図に 2 層データベースアプリケーションのアーキテクチャの関係を示します。1086018

このモデルでは，すべての Delphi アプリケーションがデータベースクライアントです。クライアントはデータベースサーバーに情報を要求したり，データベースサーバーへ情報を送ります。サーバーは複数のクライアントからの要求を同時に処理し，データへのアクセスや更新を調整します。

上手に設計された 2 層アプリケーションでは，複雑なデータモデルをアプリケーションが扱っている場合でも，ユーザーは簡単にデータの表示や編集ができます。データモデルの複雑さをアプリケーションの最終的なエンドユーザーから隠す場合でも，アプリケーション開発者自身はその複雑さを理解していなければなりません。

図に，堅固な 2 層アプリケーションを作成できるようにするために Client/Server Suite で Delphi ツールがどのように連係して動作しているか示します。

The Delphi Client/Server Suite two-tiered development environment:1086019

Delphi Professional または Delphi Standard を使っている場合でも，データベースアプリケーションの構築に費やした投資を無駄にせずに Delphi Client/Server Suite にアップグレードできます。必要であればより大型の企業規模のクライアントアプリケーション／データベースサーバーに移行できるように，Delphi ではデータベースアプリケーション開発を簡単にしています。


Understanding the architecture of a multi-tiered application
Understanding the architecture of a multi-tiered application1086020

Section topics 	参照

多層データベースモデルの場合，アプリケーションはいくつかの部分に分割され，各部分が別々のマシンに配置されます。クライアントアプリケーションはデータへのユーザーインターフェースを提供し，アプリケーションサーバー（「リモートデータブローカー」ともいいます）を通じてすべてのデータ要求と更新データを渡します。アプリケーションサーバーはリモートデータベースサーバーと直接通信します。このモデルの場合，通常はクライアントアプリケーション，アプリケーションサーバー，リモートデータベースサーバーは別々のマシン上にあります。

図に多層データベースのアーキテクチャの関係を示します。1086021

Delphi を使えばクライアントアプリケーションもアプリケーションサーバーも作成できます。図に示すように，クライアントアプリケーションはデータを確認または編集用に表示するために，データソースを通じて 1 つまたは複数のクライアントデータセットコンポーネントに接続された標準のデータベース対応コントロールを使います。各クライアントデータセットは，アプリケーションサーバーのリモートデータモジュール内にある IProvider インターフェースを通じてアプリケーションサーバーと通信します。IProvider インターフェースは，クライアントが TRemoteServer コンポーネントを初めて使ってアプリケーションサーバーへの初期接続を確立するときに，アプリケーションサーバーが最初に確立する ActiveX デュアルインターフェースです。

アプリケーションサーバーは次のどちらかの方法で IProvider インターフェースを作成します。1 つまたは複数の TProvider オブジェクトがある場合，アプリケーションサーバーはこれらのオブジェクトを使って IProvider インターフェースを作成します。このようなオブジェクトがない場合は，アプリケーションサーバーは IProvider インターフェースを自動的に作成します。一般に，Delphi に依存せずに TProvider コンポーネントを使ってインターフェースを作成すると，アプリケーションによるインターフェースの制御の度合が大きくなります。どちらの方法で作成した場合も，クライアントアプリケーションとアプリケーションサーバーの間のデータのやりとりはすべてインターフェースを通じて行われます。インターフェースは従来の Delphi データセットコンポーネントからデータを受け取り，更新データをそのコンポーネントに送ります。このコンポーネントは BDE を通じてデータベースサーバーと通信します。

通常，多層モデルでは，複数のクライアントアプリケーションが 1 つのアプリケーションサーバーと通信します。アプリケーションサーバーはどのクライアントアプリケーションにもデータベースへのゲートウェイを提供します。アプリケーションサーバーにより，開発者は，すべてのクライアントがアクセスできる中央の場所で企業規模のデータベース作業を提供できます。


Extending Delphi's database architecture
Extending Delphi's database architecture1086022

Section topics 	参照

データベースアプリケーションの作成のために組み込まれているあらゆる機能のほかに，Delphi の新しいオープンデータセットモデルを使うと，アーキテクチャを拡張し，ニーズに合わせて機能を追加できます。拡張データセットモデルでは，ニーズを明確にし，TDataSet またはその下位コンポーネントのいずれかからカスタムデータセットコンポーネントを派生させます。TDataSet からカスタムコンポーネントを派生させると，Delphi のデータベース対応コントロールを使って，ユーザーには見えないデータベースエンジン作業に重点を置けるようにして UI を作成できます。

たとえば，新しい TClientDataSet を使って作成できるような単純なクライアントアプリケーションを管理する場合，BDE を使わずに DB2 データベースに接続したいときは，カスタムデータセットコンポーネントを作成する必要があります。TDataSet はすべてのデータセットオブジェクトに共通の機能を定義します。組み込みたい追加機能を提供するのが TClientDataSet などの既存のデータセットオブジェクトであることがわかった場合は，TDataSet ではなく TClientDataSet からカスタムデータセットオブジェクトを派生させるとよいでしょう。自分で記述するコードを少なくするため，できるだけ機能が完備した既存のコンポーネントを最初に使います。これは開発者自身の責任です。Delphi のオープンデータセットアーキテクチャには，拡張性のあるさまざまな方法が提供されています。


See also1086023

多層アプリケーションの作成

クライアントデータセットの作成と使い方

項目コンポーネントの使い方

データコントロールの使い方

グリッドの使い方


Managing database sessions
Managing database sessions1087001

Section topics 	参照

スタンドアロンのフルクライアントデータベースアプリケーションとデータベースアプリケーションサーバーの両方とも，ボーランドデータベースエンジン（BDE）を通じてデータベースと通信します。アプリケーションのデータベース接続，ドライバ，カーソル，問い合わせなどは，1 つまたは複数の BDE セッションのコンテキスト内で管理されます。セッションはデータベース接続などの一連のデータベースアクセス処理を分離しますが，アプリケーションの別のインスタンスを開始する必要はありません。

Delphi アプリケーションでは，TSession コンポーネントと TSessionList コンポーネントを使って BDE セッションを管理できます。アプリケーション内の各 TSession コンポーネントが 1 つの BDE セッションをカプセル化します。アプリケーション内のすべてのセッションは，1 つの TSessionList コンポーネントによって管理されます。

すべてのデータベースアプリケーションには，デフォルトの BDE セッションをカプセル化する，Session というセッションコンポーネントが自動的に提供されます。必要であれば追加セッションコンポーネントをアプリケーションで宣言，作成，操作できます。

すべてのデータベースアプリケーションには，アプリケーションのすべてのセッションコンポーネントを管理できる，Sessions というセッションリストコンポーネントも自動的に提供されます。

この章では，セッションコンポーネントとセッションリストコンポーネントについて説明し，フルクライアントデータベースアプリケーションとデータベースアプリケーションサーバーの中でこれらのコンポーネントを使って BDE セッションを制御する方法について説明します。

メモ	デフォルトのセッションコンポーネントとセッションリストコンポーネントは，そのままでほとんどのアプリケーションで変更することなく使うことができます。たとえば1つのデータベースに対して同時に異なる問い合わせを行うような場合には，セッションを操作して複数のセッションを作る場合があります。


Working with a session component
Working with a session component1087002

Section topics 	参照

セッションコンポーネントを使うと，アプリケーション内の一連のデータベース接続をグローバルに管理できます。ローカル/サーバーを問わず，データベースアプリケーションを作成すると，自動的に Session というセッションコンポーネントが作成されます。アプリケーションにデータベースコンポーネントやデータセットコンポーネントを追加すると，それらのコンポーネントは自動的にこのデフォルトセッションに関連付けられます。また，セッションコンポーネントは，パスワード保護された Paradox ファイルへのアクセスを制御し，ネットワーク上で Paradox ファイルを共有するためのディレクトリ位置を指定します。アプリケーションは，セッションのプロパティ，イベント，およびメソッドを使うことでデータベース接続や Paradox ファイルへのアクセスを制御できます。

アプリケーション内のすべてのデータベース接続を制御するのにデフォルトセッションを使えます。または，アプリケーション内のデータベース接続のサブセットを制御するために，追加セッションコンポーネントを設計時に作成したり，実行時に動的に作成したりできます。

アプリケーションによっては，セッションコンポーネントの追加が必要です。同一のデータベースに対して同時に複数の問い合わせを実行するアプリケーションなどです。この場合，それぞれの問い合わせが，問い合わせ自身のセッション下で実行されなければなりません。マルチスレッドデータベースアプリケーションも複数のセッションが必要です。複数のセッションを使うアプリケーションは，セッションリストコンポーネント Sessions を通じてセッションを管理しなければなりません。複数のセッションの管理については，「複数のセッションの管理」を参照してください。


Using the default session
Using the default session1087003

Section topics 	参照

すべてのデータベースアプリケーションには，デフォルトセッションが自動的に提供されます。データベースアプリケーションを実行するたびに，そのデータベースアプリケーションの「Session」というデフォルトセッションコンポーネントが作成されます（このコンポーネントの SessionName は「Default」なので注意してください）。デフォルトセッションでは，別のセッションに関連付けられていないすべてのデータベースコンポーネントを，それらが一時的か持続的かにかかわらず，グローバルに制御できます。一時的なデータベースコンポーネントは，開発者が作成するデータベースコンポーネントに関連付けられていないデータセットを開くときの実行時にデフォルトセッションによって作成されます。持続的なコンポーネントは，アプリケーションで明示的に作成されます。設計時にはデータモジュールまたはフォームにデフォルトセッションは表示されませんが，実行時にはコードでデフォルトセッションのプロパティやメソッドにアクセスできます。

データベースコンポーネントを作成すると，そのコンポーネントは自動的にデフォルトセッションに関連付けられます。作成するデータベースコンポーネントを明示的に指定したセッションに関連付けなければならないのは，デフォルトセッションがすでに開いているデータベースに対して，そのコンポーネントが同時に問い合わせを実行する場合だけです。この場合，マルチスレッドデータベースアプリケーションを作成することになり，追加スレッドを処理する追加セッションをスレッドごとに 1 つずつ作成しなければなりません。

アプリケーションが以下のことをする必要がなければ，デフォルトセッションを使うためにコードを記述する必要はありません。

デフォルトセッションのプロパティを変更する。自動的に生成されるデータベースコンポーネントのデータベース接続をどのようなときに自動的に維持または切断するかを指定する場合など

デフォルトセッションのイベントに応答する。パスワード保護された Paradox ファイルにアプリケーションがアクセスを試みる場合など

デフォルトセッションのメソッドを実行する。ユーザーが開始する操作に応じてデータベースを開いたり閉じたりする場合など

NetFileDir プロパティを設定して，ネットワーク上の Paradox テーブルにアクセスする。PrivateDir プロパティをローカルドライブに設定してパフォーマンスを向上させる場合など

データベースコンポーネントを設計時にアプリケーションに追加するか実行時に動的に作成する場合，明示的にほかのセッションに関連付けないと，それらのデータベースコンポーネントは自動的にデフォルトセッションに関連付けられます。データベースコンポーネントに関連付けられていないデータセットをアプリケーションが開こうとすると，実行時に自動的にそのデータセット用のデータベースコンポーネントが作成されてデフォルトセッションに関連付けられ，デフォルトセッションのプロパティに基づいてデータベースコンポーネントのいくつかの主なプロパティに初期値が代入されます。

これらのプロパティの中でもっとも重要なのが KeepConnections です。KeepConnections は，アプリケーションがどのようなときにデータベース接続を維持または切断するかを指定します。KeepConnections については，「デフォルトのデータベース接続動作の指定」を参照してください。デフォルトセッションおよびアプリケーション内で作成する追加セッションに使う，TSession コンポーネントのその他のプロパティ，イベント，メソッドについては，この章で後述します。


Creating additional sessions
Creating additional sessions1087004

Section topics 	参照

デフォルトセッションを補足する独自のセッションを作成できます。設計時にデータモジュール（またフォーム）にセッションを追加します。オブジェクトインスペクタで追加したセッションのプロパティを設定し，イベントハンドラを記述することで，追加したセッションのメソッドを呼び出すコードを記述できます。実行時にセッションを作成し，セッションのプロパティを設定して，セッションのメソッドを呼び出すこともできます。この節では，実行時にセッションを作成および解放する方法について説明します。

メモ	アプリケーションが 1 つのデータベースに対して同時に問い合わせを実行しない場合，またはアプリケーションがマルチスレッドでない場合，セッションを追加するかどうかは任意なので注意してください。

セッションコンポーネントを実行時に動的に作成し追加する手順は次のとおりです。

1.	TSession 変数を宣言します。

2.	新しいセッションをインスタンス化するために Create コンストラクタを呼び出します。Create は，セッションのデータベースコンポーネントの空のリストを設定し，セッションの BDE コールバックの空のリストを設定し，KeepConnections プロパティを True に設定して，アプリケーションのセッションリストコンポーネントが管理するセッションリストにセッションを追加します。

3.	新しいセッションの SessionName プロパティにユニークな名前を設定します。このプロパティは，データベースコンポーネントをセッションに関連付けるのに使われます。SessionName プロパティについては，「セッション名の指定」を参照してください。

4.	セッションをアクティブにし，必要であればセッションのプロパティを調整します。

次のコードにこの手順を示します。

var

SecondSession: TSession;

begin

SecondSession := TSession.Create;

with SecondSession do

try

SessionName := 'SecondSession';

KeepConnections := False;

Open;

end;

.

.

.

finally

SecondSession.Free;

end;

end;

メモ	デフォルトセッションに対して Free を呼び出さないでください。

セッションを作成したり開いたりする処理は，TSessionList の OpenSession メソッドを使っても管理できます。OpenSession はまだセッションが存在していない場合にだけセッションを作成するため，OpenSession を使う方が Create を呼び出すよりも安全です。OpenSession の使い方については，「複数のセッションの管理」を参照してください。


Naming a session
Naming a session1087005

Section topics 	参照

セッションの SessionName プロパティは，データベースとデータセットをセッションに関連付けられるようにセッションに名前を付けるのに使います。デフォルトセッションの SessionName は「Default」です。作成する追加セッションコンポーネントの SessionName プロパティには，それぞれユニークな値を設定しなければなりません。

データベースとデータセットの各コンポーネントには，セッションコンポーネントの SessionName プロパティに対応する SessionName プロパティがあります。データベースまたはデータセットコンポーネントの SessionName プロパティを空白にしておくと，それらのコンポーネントは自動的にデフォルトセッションに関連付けられます。データベースまたはデータセットコンポーネントの SessionName には，作成したセッションコンポーネントの SessionName に対応する名前を割り当てることもできます。たとえば次のコードは，デフォルトの TSessionList コンポーネント Sessions の OpenSession メソッドを使って新しいセッションコンポーネントを開き，そのコンポーネントの SessionName を「InterBaseSession」に設定し，セッションをアクティブにして，既存のデータベースコンポーネント Database1 をこのセッションに関連付けます。

var

IBSession: TSession;

...

begin

IBSession := Sessions.OpenSession('InterBaseSession');

Database1.SessionName := 'InterBaseSession';

end;

複数のセッションを制御するための TSessionList コンポーネント（特に Sessions）の使い方については，「複数のセッションの管理」を参照してください。


Activating a session
Activating a session1087006

Section topics 	参照

Active は論理プロパティであり，セッションに関連付けられたデータベースコンポーネントとデータセットコンポーネントが開いているかどうかを表します。このプロパティを使うと，セッションのデータベース接続とデータセット接続の現在の状態を読み出したり変更したりできます。

セッションの現在の状態を確認するには，Active を調べます。Active が False（デフォルト）の場合，セッションに関連付けられたすべてのデータベースとデータセットは閉じています。True の場合，データベースとデータセットは開いています。

Active を True に設定すると，セッションの OnStartup イベントが呼び出され，NetFileDir プロパティと PrivateDir プロパティに値が代入されていればこの 2 つのプロパティが設定され，ConfigMode プロパティが設定されます。OnStartup イベントハンドラを記述すると，その他の特定のデータベース起動処理を実行できます。OnStartup については，「パスワード保護された Paradox テーブルの操作」を参照してください。NetFileDir と PrivateDir の両プロパティは，Paradox テーブルへの接続以外には使われません。NetFileDir と PrivateDir については，「コントロールファイルの位置を指定する」および「一時ファイルの位置を指定する」を参照してください。ConfigMode は，セッションのコンテキスト内で作成される BDE エリアスを BDE がどのように処理するかを決めるためのものです。ConfigMode については，「エリアスの可視性を指定する」を参照してください。セッション内でデータベースコンポーネントを開く場合については，「データベース接続の作成と開閉」を参照してください。

セッションをアクティブにした後，OpenDatabase メソッドを呼び出すとそのセッションのデータベース接続を開くことができます。

データモジュールまたはフォームに入れるセッションコンポーネントの場合，開いているデータベースまたはデータセットがあるときに Active を False に設定すると，それらのデータベースやデータセットは閉じます。実行時にデータベースやデータセットを閉じると，それらに関連付けられているイベントが呼び出される場合があります。

メモ	設計時にデフォルトセッションの Active を False に設定することはできません。実行時にデフォルトセッションを閉じることはできますが，できるだけ閉じないでください。

作成するセッションコンポーネントの場合，設計時にオブジェクトインスペクタを使って Active を False に設定すると，プロパティの変更 1 つでセッションのすべてのデータベースアクセスを無効にできます。アプリケーションの設計時にリモートデータベースを一時的に利用できないことで例外を受け取りたくない場合，このようにするとよいでしょう。

セッションの Open メソッドと Close メソッドを使っても，デフォルトセッション以外のセッションを実行時にアクティブや非アクティブにできます。たとえば次の 1 行のコードだけで，セッションで開いているすべてのデータベースとデータセットが閉じます。

Session1.Close;

このコードは Session1 の Active プロパティを False に設定します。セッションの Active プロパティが False の場合，その後でアプリケーションがデータベースまたはデータセットを開こうとすると，Active が True に再設定され，セッションの OnStartup イベントがあれば呼び出されます。実行時のセッションの再アクティブ化を明示的に記述することもできます。次のコードは Session1 を再びアクティブにします。

Session1.Open;

メモ	セッションがアクティブな場合，データベース接続を個別に開いたり閉じたりることもできます。詳細については，「1 つのデータベース接続を閉じる」を参照してください。


Customizing session start-up
Customizing session start-up1087007

Section topics 	参照

セッション用に OnStartup イベントハンドラを記述すると，セッションの起動時の動作をカスタマイズできます。OnStartup はセッションがアクティブになると発生します。セッションは，最初に作成されるときと，その後で Active プロパティが False から True に変更されるたびにアクティブになります。たとえば，セッションに関連付けられたデータベースまたはデータセットが開き，それ以外のデータベースまたはデータセットが現在 1 つも開いていないときです。


Specifying default database connection behavior
Specifying default database connection behavior1087008

Section topics 	参照

KeepConnections は，実行時に作成される一時データベースコンポーネントの KeepConnection プロパティにデフォルト値を与えます。KeepConnection は，データベースコンポーネント用に確立されたデータベース接続を，そのデータベース接続のすべてのデータセットが閉じるときにどうするかを決めます。True（デフォルト）の場合，アクティブなデータセットがなくても持続的なデータベース接続が維持されます。False の場合，すべてのデータセットが閉じると，ただちにデータベース接続が切断されます。

メモ	データモジュールまたはフォームに明示的に入れるデータベースコンポーネントの接続の持続性は，そのデータベースコンポーネントの KeepConnection プロパティによって制御されます。設定が異なる場合，必ずデータベースコンポーネントの KeepConnection がセッションの KeepConnections プロパティをオーバーライドします。セッション内での個々のデータベース接続の制御の詳細については，「データベース接続の作成と開閉」を参照してください。

リモートサーバー上のデータベースに関連付けられたすべてのデータセットを頻繁に開いたり閉じたりするアプリケーションの場合，KeepConnections を常に True に設定しておく必要があります。True の場合，セッションの存続中に接続を 1 度開いて閉じるだけですむので，ネットワークのトラフィックが減り，データアクセス速度が向上します。True でない場合は，接続を閉じたり再確立するたびに，データベースのアタッチおよびデタッチのオーバーヘッドが発生します。

メモ	セッションの KeepConnections が True の場合でも，DropConnections メソッドを呼び出せば，すべての一時データベースコンポーネントの非アクティブなデータベース接続を閉じて一時データベースコンポーネントを解放できます。DropConnections の詳細については，「一時データベース接続の切断」を参照してください。

たとえば次のコードは，デフォルトセッション中のアクティブではなくなった接続を閉じ，すべての一時データベースコンポーネントを解放します。

Session.DropConnections;


Creating, opening, and closing database connections
Creating, opening, and closing database connections1087009

Section topics 	参照

セッション内でデータベース接続を開くには，OpenDatabase メソッドを呼び出します。OpenDatabase は，開きたいデータベースの名前を 1 つパラメータとして取ります。この名前は BDE エリアスです。Paradox または dBASE では，完全に限定されたパス名の場合もあります。たとえば次の文は，デフォルトセッションを使い，DBDEMOS エリアスが指すデータベースのデータベース接続を開こうとします。

var

DBDemosDatabase: TDatabase;

begin

Session.OpenDatabase('DBDEMOS');

.

.

.

OpenDatabase は，自身のセッションがまだアクティブでなければアクティブにしてから，指定されたデータベース名がセッションのいずれかのデータベースコンポーネントの DatabaseName プロパティと一致するかどうかを確認します。名前が既存のデータベースコンポーネントと一致しない場合，OpenDatabase は，指定された名前を使って一時データベースコンポーネントを作成します。OpenDatabase を呼び出すと，そのデータベースの参照カウンタが 1 つ増えます。参照カウンタが 0 でない限り，データベースは開いたままです。最後に，該当のデータベースコンポーネントの Open メソッドを呼び出してサーバーに接続します。

Closing a single database connection1087010

CloseDatabase メソッドを使うと個々のデータベース接続を閉じることができ，Close メソッドを使うとセッションの接続を一度にすべて閉じることができます。CloseDatabase を呼び出すと，そのデータベースの参照カウンタが 1 つ減ります。参照カウンタが 0 になると，データベースが閉じて解放されます。CloseDatabase は，閉じるデータベースの名前を 1 つパラメータとして取ります。この名前は BDE エリアスです。Paradox または dBASE のテーブルでは，完全に限定されたパス名の場合もあります。たとえば次の文は，DBDEMOS エリアスが指すデータベース接続を閉じます。

CloseDatabase('DBDEMOS');

指定したデータベース名が一時データベースコンポーネントに関連付けられていて，セッションの KeepConnections プロパティが False の場合，その一時データベースコンポーネントが解放され，接続が完全に閉じます。

メモ	KeepConnections が False の場合，一時データベースコンポーネントに関連付けられている最後のデータセットが閉じると，その一時データベースコンポーネントが自動的に閉じ，解放されます。アプリケーションは，この時点より前にいつでも CloseDatabase を呼び出して強制的に閉じることができます。KeepConnections が True の場合に一時データベースコンポーネントを解放するには，その一時データベースコンポーネントの Close メソッドを呼び出してから，セッションの DropConnections メソッドを呼び出します。

データベースコンポーネントが持続的な場合（つまりアプリケーションが明示的にコンポーネントを宣言してインスタンス化する場合）にセッションの KeepConnections プロパティが False のときは，CloseDatabase がデータベースコンポーネントの Close メソッドを呼び出して接続を閉じます。

メモ	持続的なデータベースコンポーネントの CloseDatabase を呼び出しても，実際には接続は閉じません。接続を閉じるには，データベースコンポーネントの Close メソッドを直接呼び出します。

Closing all database connections1087011

一度にすべてのデータベース接続を閉じるには，以下の 2 つの方法があります。

セッションの Active プロパティを False に設定する

セッションの Close メソッドを呼び出す

Active を False に設定すると，自動的に Close メソッドが呼び出されます。Close は，一時データベースコンポーネントを解放してから持続的な各データベースコンポーネントの Close メソッドを呼び出すことによって，アクティブなすべてのデータベースから切断します。最後に，Close がセッションの BDE ハンドルを nil に設定します。


Dropping temporary database connections
Dropping temporary database connections1087012

Section topics 	参照

セッションの KeepConnections プロパティが True（デフォルト）の場合は，一時データベースコンポーネントが使っていたデータセットがすべて閉じても，一時データベースコンポーネントのデータベース接続が維持されます。DropConnections メソッドを呼び出すと，これらの接続を閉じて，セッションの非アクティブなすべての一時データベースコンポーネントを解放できます。たとえば次のコードは，デフォルトセッションの非アクティブな一時データベースコンポーネントをすべて解放します。

Session.DropConnections;

アクティブなデータセットが 1 つでもあれば，DropConnections を呼び出しても一時データベースコンポーネントは切断も解放もされずにアクティブを保ちます。このようなコンポーネントを解放するには Close を呼び出します。


Searching for a database connection
Searching for a database connection1087013

Section topics 	参照

特定のデータベースコンポーネントがすでにセッションに関連付けられているかどうかを確認するには，セッションの FindDatabase メソッドを使います。FindDatabase は，検索するデータベースの名前を 1 つパラメータとして取ります。この名前は BDE エリアスまたはデータベースコンポーネントの名前です。Paradox または dBASE では，完全に限定されたパス名の場合もあります。たとえば次の文は，DBDEMOS エリアスを使ってデフォルトセッションのデータベースコンポーネントを検索し，見つからなければデータベースコンポーネントを作成して開きます。

var

DB: TDatabase;

begin

DB := Session.FindDatabase('DBDEMOS');

if DB = nil then	{セッションにデータベースがなければ}

DB := Session.OpenDatabase('DBDEMOS');	{作成して開く}

if Assigned(DB) and DB.Active then

begin

DB.StartTransaction;

.

.

.

end;

end;

FindDatabase は，一致するものが見つかった場合はそのデータベースコンポーネントを返し，それ以外の場合は nil を返します。


Retrieving information about a session
Retrieving information about a session1087014

Section topics 	参照

セッションの情報用メソッドを使うと，セッションとセッションのデータベースコンポーネントについての情報を取り出せます。たとえば，セッションで既知のすべてのエリアスの名前を取り出すメソッドや，セッションが使う特定のデータベースコンポーネントに関連付けられたテーブルの名前を取り出すメソッドがあります。表に，セッションコンポーネントの情報用メソッドの概要を示します。

メソッド	用途
GetAliasDriverName	データベースの特定のエリアスの BDE ドライバを取り出す
GetAliasNames	データベースの BDE エリアスのリストを取り出す
GetAliasParams	データベースの特定の BDE エリアスのパラメータリストを取り出す
GetConfigParams	BDE 環境設定ファイルから特定の環境設定情報を取り出す
GetDatabaseNames	BDE エリアスのリストと現在使われているすべての TDatabase コンポーネントの名前を取り出す
GetDriverNames	現在インストールされているすべての BDE ドライバの名前を取り出す
GetDriverParams	特定の BDE ドライバのパラメータリストを取り出す
GetStoredProcNames	特定のデータベースのすべてのストアドプロシージャの名前を取り出す
GetTableNames	特定のデータベースの特定のパターンに一致するすべてのテーブルの名前を取り出す
GetAliasDriverName を除き，これらのメソッドは，アプリケーションが宣言して管理する文字列リストに値のセットを返します。GetAliasDriverName は，セッションが使っている特定のデータベースコンポーネントの現在の BDE ドライバの名前を 1 つの文字列で返します。

たとえば次のコードは，すべてのデータベースコンポーネント名と，デフォルトセッションで既知のエリアスを取り出します。

var

List: TStringList;

begin

List := TStringList.Create;

try

Session.GetDatabaseNames(List);

.

.

.

finally

List.Free;

end;

end;

セッションの情報用メソッドについては，オブジェクトおよびコンポーネントライブラリのオンラインヘルプを参照してください。


Working with BDE aliases
Working with BDE aliases1087015

Section topics 	参照

通常セッションは一連のデータベース接続をカプセル化するので，1 つのプロパティとセッションコンポーネントの多くのメソッドが BDE エリアスを操作します。セッションに関連付けられたデータベースコンポーネントは，それぞれ BDE エリアスを持ちます。ただし，Paradox や dBASE のテーブルにアクセスする場合は，必要であれば，エリアスのかわりに完全に限定されたパス名が使われることがあります。このプロパティとこれらのメソッドの用途は，以下の 3 つのグループに分けられます。

可視性の決定

エリアスとドライバの情報の取り出し

エリアスの作成，変更，削除

以下の各節では，これらの機能分野について説明します。

Specifying alias visibility1087016

セッションの ConfigMode プロパティは，セッションに対する BDE エリアスの可視性を決定します。ConfigMode は，どのセッションが可視であるかを示しています。デフォルトは cmAll です。ConfigMode が cmAll の場合，セッションは，セッション内で作成されるエリアス，ユーザーのシステム上の BDE 環境設定ファイルにあるエリアス，および BDE がメモリ内に保持するエリアスをすべて見ることができます。

ConfigMode は主に，アプリケーションがエリアスの可視性をセッションレベルで指定して制限できるようにするために使います。たとえば，ConfigMode を cmSession に設定すると，セッションはセッション内で作成されるエリアスしか見えなくなります。BDE 環境設定ファイル内とメモリ内にあるその他のすべてのエリアスが使えなくなります。

ConfigMode とその設定については，オブジェクトおよびコンポーネントライブラリのオンラインヘルプを参照してください。

Making session aliases visible to other sessions and applications1087017

セッション内でエリアスを作成すると，エリアスのコピーがメモリに格納されます。デフォルトでは，コピーを作成したセッションだけがそのコピーを見ることができます。同一のアプリケーション内のほかのセッションがこのエリアスを見ることができるのは，ConfigMode プロパティが cmAll，cmPersistent の場合だけです。

すべてのセッションとほかのアプリケーションがエリアスを使えるようにするには，アプリケーションでセッションの SaveConfigFile メソッドを使います。SaveConfigFile は，メモリ内のエリアスを BDE 環境設定ファイルに書き込みます。BDE 対応のほかのアプリケーションは，この BDE 環境設定ファイルからエリアスを読み出して使えます。

Determining known aliases, drivers, and parameters1087018

セッションコンポーネントの以下の 5 つのメソッドを使うと，パラメータ情報とドライバ情報も含めて，BDE のエリアスについての情報をアプリケーションで取り出せます。

GetAliasName	セッションがアクセスできるエリアスのリストを返す

GetAliasParam	指定したエリアスのパラメータのリストを返す

GetAliasDriverNam	エリアスが使う BDE ドライバの名前を含む文字列を返す

GetDriverName	セッションが利用できるすべての BDE ドライバのリストを返す

GetDriverParam	指定したドライバのドライバパラメータを返す

セッションの情報用メソッドの使い方の詳細については，「セッションについての情報の取り出し」を参照してください。

Creating, modifying, and deleting aliases1087019

セッションは，存続期間中にエリアスを作成，変更，削除できます。AddAlias メソッドは，SQL データベースサーバーの新しい BDE エリアスを作成します。AddStandardAlias は，Paradox，dBASE，または ASCII の各テーブルの新しい BDE エリアスを作成します。

AddAlias はパラメータを 3 つ取ります。エリアスの名前を含む文字列，使う SQL Link ドライバを指定する文字列，およびエリアスのパラメータが入る文字列リストの 3 つです。たとえば次の文は，InterBase サーバーにアクセスするための新しいエリアスをデフォルトセッションに追加します。

var

AliasParams: TStringList;

begin

AliasParams := TStringList.Create;

try

with AliasParams do

Add('OPEN MODE=READ');

Add('USER NAME=TOMSTOPPARD');

Add('SERVER NAME=ANIMALS:/CATS/PEDIGREE.GDB');

end;

Session.AddAlias('CATS', 'INTRBASE', AliasParams);

.

.

.

finally

AliasParams.Free;

end;

end;

AddAlias については，オブジェクトおよびコンポーネントライブラリのオンラインヘルプを参照してください。BDE エリアスと SQL Link ドライバについては，BDE のオンラインヘルプを参照してください。

AddStandardAlias は 3 つのパラメータを取ります。エリアス名，アクセスする Paradox テーブルまたは dBASE テーブルへの完全に限定されたパス，および拡張子を持たないテーブルを開こうとするときに使うデフォルトドライバの名前の 3 つです。たとえば次の文は，Paradox テーブルにアクセスするための新しいエリアスを作成します。

AddStandardDriver('MYDBDEMOS', 'C:\TESTING\DEMOS\', 'Paradox');

AddStandardAlias についての詳細は，オブジェクトとコンポーネントのライブラリのオンラインリファレンスを参照してください。BDE エリアスについての詳細は，BDE のオンラインヘルプを参照してください。

メモ	セッションに追加したエリアスを使えるのは，そのセッションと，ConfigMode プロパティが cmpersistent に設定されているセッションに限られます。新しく作成したエリアスをすべてのアプリケーションで使えるようにするには，エリアスを作成した後で SaveConfigFile を呼び出します。ConfigMode については，「BDE エリアスの操作」を参照してください。

エリアスを作成した後，ModifyAlias を呼び出すとエリアスのパラメータを変更できます。ModifyAlias は 2 つのパラメータを取ります。変更するエリアスの名前と，変更するパラメータおよびそれらの値を含む文字列リストの 2 つです。たとえば次の文は，デフォルトセッション内で CATS エリアスの OPEN MODE パラメータを READ/WRITE に変更します。

var

List: TStringList;

begin

List := TStringList.Create;

with List do

begin

Clear;

Add('OPEN MODE=READ/WRITE');

end;

Session.ModifyAlias('CATS', List);

List.Free;

.

.

.

セッション内で以前に作成したエリアスを削除するには，DeleteAlias メソッドを呼び出します。DeleteAlias は，削除するエリアスの名前を 1 つパラメータとして取ります。DeleteAlias を使うと，セッションがそのエリアスを使えなくなります。

メモ	SaveConfigFile を呼び出して BDE 環境設定ファイルに書き込んであるエリアスは，DeleteAlias を使っても環境設定ファイルから削除されません。DeleteAlias を呼び出した後でエリアスを環境設定ファイルから削除するには，もう一度 SaveConfigFile を呼び出します。


Iterating through a session's database components
Iterating through a session's database components1087020

Section topics 	参照

セッションコンポーネントの Databases と DatabaseCount という 2 つのプロパティを使うと，セッションに関連付けられているすべてのデータベースコンポーネントに対して処理を繰り返し実行できます。

Databases は，セッションに関連付けられている，現在アクティブなすべてのデータベースコンポーネントの配列です。DatabaseCount プロパティと一緒に Databases を使うと，アクティブなすべてのデータベースコンポーネントに対して，特定または汎用の処理を繰り返し実行できます。

DatabaseCount は，セッションに関連付けられている，現在アクティブなデータベースの数を表す整数のプロパティです。セッションの存続期間中に接続を開くかまたは閉じると，この数が変わることがあります。たとえば，セッションの KeepConnections プロパティが False で，すべてのデータベースコンポーネントが実行時に必要であれば Delphi によって作成される場合，データベースを作成するたびに，DatabaseCount は 1 ずつ増えます。また，作成されたデータベースを閉じるたびに，DatabaseCount は 1 ずつ減ります。DatabaseCount がゼロの場合，そのセッションには現在アクティブなデータベースコンポーネントはありません。

通常 DatabaseCount は，アクティブなデータベースコンポーネントに共通する処理を実行するために Databases プロパティと一緒に使われます。たとえば次のコードは，デフォルトセッション内でアクティブな各データベースの KeepConnection プロパティを True に設定します。

var

MaxDbCount: Integer;

begin

with Session do

if DatabaseCount > 0 then

for MaxDbCount := 1 to DatabaseCount do

Databases{MaxDbCount].KeepConnection := True;

end;

end;


Specifying Paradox directory locations
Specifying Paradox directory locations1087021

Section topics 	参照

セッションコンポーネントの NetFileDir と PrivateDir という 2 つのプロパティは，Paradox テーブルを使って作業するアプリケーション専用です。NetFileDir は，Paradox のネットワークコントロールファイル PDOXUSRS.NET を格納するディレクトリを指定します。PDOXUSRS.NET は，ネットワークドライブ上での Paradox テーブルの共有を管理するファイルです。Paradox テーブルの共有が必要なすべてのアプリケーションが，ネットワークコントロールファイルの同一のディレクトリ（通常はネットワークファイルサーバー上のディレクトリ）を指定しなければなりません。

PrivateDir は，ローカル SQL 文を処理するために BDE が生成するファイルなどの一時テーブル処理ファイルを格納するディレクトリを指定します。

Specifying the control file location1087022

データベースの特定のエリアスについては，ボーランドデータベースエンジン（BDE）の環境設定ファイルから NetFileDir の値が生成されます。開発者が NetFileDir を設定する場合，その値が BDE の環境設定の値をオーバーライドするので，新しい値かどうかを必ず検証してください。

NetFileDir の値は，設計時にオブジェクトインスペクタで指定できます。実行時にコードで NetFileDir を設定したり変更することもできます。次のコードは，アプリケーションの起動ディレクトリ位置をデフォルトセッションの NetFileDir に設定します。

Session.NetFileDir := ExtractFilePath(ParamStr(0));

メモ	NetFileDir を変更できるのは，アプリケーションで Paradox ファイルを開いていない場合だけです。実行時に NetFileDir を変更する場合は，ネットワークユーザーが共有する正しいネットワークディレクトリを NetFileDir が指しているか確認してください。

Specifying a temporary files location1087023

PrivateDir プロパティに値が指定されていない場合，BDE は初期化時に自動的にカレントディレクトリを使います。アプリケーションをネットワークファイルサーバーから直接実行する場合は，PrivateDir をローカルドライブに設定することにより実行時のパフォーマンスを向上できます。

メモ	PrivateDir の設定は，データベースを開く前に行ってください。データベースが開かれているとエラー「Directory busy」が生成されます。

次のコードは，デフォルトセッションの PrivateDir プロパティの設定をユーザーの C:\TEMP ディレクトリに変更します。

Session.PrivateDir := 'C:\TEMP';

重要	PrivateDir は必ずサブディレクトリに設定してください。


Working with password-protected Paradox tables
Working with password-protected Paradox tables1087024

Section topics 	参照

セッションコンポーネントには，パスワード保護された Paradox ファイルへのアクセス管理専用に使われる 4 つのメソッドと 1 つのイベントがあります。メソッドは AddPassword，GetPassword，RemoveAllPasswords，RemovePassword で，イベントは OnPassword です。

AddPassword 手続きを使うと，アクセスにパスワードが必要な暗号化された Paradox テーブルを開く前にアプリケーションがセッションにパスワードを提供できます。AddPassword は，パラメータとしてパスワードからなる文字列を指定します。異なるパスワードで保護された複数の Paradox ファイルにアクセスするために，AddPassword を必要なだけ何回でも呼び出してパスワードを追加していくことができます。

メモ	AddPassword を呼び出しをせず，パスワード保護された Paradox ファイルへのアクセスに使う 1 つまたは複数のパスワードが指定されていず，パスワードの必要なテーブルを開こうとしたアプリケーションに OnPassword イベントハンドラがないときは，ユーザーにパスワードの入力を求めるダイアログボックスが表示されます。

RemovePassword は，以前に追加したパスワードをメモリから削除します。RemovePassword は，パラメータとして削除するパスワードからなる文字列を指定します。RemoveAllPasswords は，以前に追加したすべてのパスワードをメモリから削除します。

GetPassword を使うと，セッションの OnPassword イベントが発生します。OnPassword イベントが呼び出されるのは，アプリケーションが Paradox テーブルを初めて開こうとしたときにアクセス権の不十分なことが BDE から報告された場合だけです。BDE に対し，パスワードを処理して提供するための OnPassword イベントを記述してもかまいませんし，Delphi のデフォルトのパスワード処理を使ってもかまいません。デフォルトのパスワード処理では，ユーザーにパスワードの入力を求めるダイアログボックスが表示されます。


Managing multiple sessions
Managing multiple sessions1087025

Section topics 	参照

データベース処理を実行する複数のスレッドを使う単独のアプリケーションを作成する場合，スレッドごとに追加セッションを 1 つ作成しなければなりません。コンポーネントパレットの［Data Access］ページには，設計時にデータモジュールまたはフォームに追加できる TSession コンポーネントがあります。

重要	TSession コンポーネントを追加する場合，デフォルトセッションの SessionName プロパティと衝突しないように，ユニークな値を TSession コンポーネントの SessionName プロパティに設定する必要もあります。

設計時に TSession コンポーネントを入れると，実行時にアプリケーションに必要になるスレッド（および，それによるセッション）の数が静的であると仮定されます。しかし，アプリケーションがセッションを動的に作成しなければならないことがよくあります。セッションを動的に作成するには，実行時にグローバル関数 Sessions.OpenSessionを呼び出します。

Sessions.OpenSession には，アプリケーションのすべてのセッション名でユニークなセッション名のパラメータが 1 つ必要です。次のコードは，ユニークに生成される名前を持つ新しいセッションを動的に作成してアクティブにします。

Sessions.OpenSession('RunTimeSession' + IntToStr(Sessions.Count + 1));

この文では，現在のセッション数を取り出して，その値に 1 を足すことによって，新しいセッションのユニークな名前を生成しています。実行時にセッションを動的に作成して廃棄する場合，このコード例は期待どおりに動作しないことに注意してください。この例は，複数のセッションを管理するために Sessions のプロパティとメソッドをどう使うかを示したものです。

Sessions は TSessionList 型のコンポーネントで，データベースアプリケーション用に自動的にインスタンス化されます。マルチスレッドデータベースアプリケーションで複数のセッションを管理するには，Sessions のメソッドとプロパティを使います。表 2.2 に TSessionList コンポーネントのプロパティとメソッドの概要を示します。

プロパティまたはメソッド	用途
Count プロパティ	セッションリスト内のセッション数（アクティブと非アクティブの両方）を返す
FindSession メソッド	指定された名前のセッションをセッションリストから検索し，そのセッションコンポーネントを返す。指定された名前のセッションがない場合は nil を返す。空白のセッション名を渡した場合は，デフォルトセッション Session を返す
GetSessionNames メソッド	現在インスタンス化されているすべてのセッションコンポーネントの名前の文字列リストを返す。最低でも 1 つの文字列（デフォルトセッションの 「Default」）を必ず返す。実際のデフォルトセッション名は，空白の文字列であることに注意する
List プロパティ	指定されたセッション名のセッションコンポーネントを返す。その名前のセッションがない場合，例外が生成される
OpenSession メソッド	指定されたセッション名で新しいセッションを作成してアクティブにするか，その名前の既存のセッションを再びアクティブにする
Sessions プロパティ	順序値でセッションリストにアクセスする。Sessions がデフォルトのプロパティなので，Sessions.Sessions[0] ではなく，Sessions[0] で呼び出せる
マルチスレッドアプリケーションでの Sessions のプロパティとメソッドの例として，データベース接続を開くときの動作について考えます。接続がすでに存在するかどうかを確認するには，Sessions プロパティを使って，セッションリストにある各セッションをデフォルトセッションから順にたどっていきます。セッションコンポーネントごとに，Databases プロパティを調べて，問題のデータベースが開いているか確認します。必要なデータベースをすでにほかのスレッドが使っている場合，リスト内の次のセッションを調べます。

既存のスレッドがデータベースを使っていない場合，そのセッション内で接続を開けます。

一方，既存のすべてのスレッドがデータベースを使っている場合は，別のデータベース接続を開くための新しいセッションを開かなければなりません。


Using a session component in data modules
Using a session component in data modules1087026

Section topics 	参照

セッションコンポーネントをデータモジュールに入れても問題はありません。ただし，セッションコンポーネントが 1 つでも含まれているデータモジュールをオブジェクトリポジトリに入れた場合，AutoSessionName プロパティが True に設定されていることを確認してください。


See also1087027

TSession

TSessionList

データアクセスコンポーネント

TDataModule

ユーザーズガイド第 7 章「データモジュールの使い方」


Connecting to databases
Connecting to databases1088001

Section topics 	参照

Delphi アプリケーションとデータベースの接続は，TDatabase コンポーネントによってカプセル化されます。データベースコンポーネントは，1 つのデータベースへの接続をボーランドデータベースエンジン（BDE）セッションのコンテキストでアプリケーションの中にカプセル化します。この章では，データベースコンポーネントについてとそれを使ってデータベース接続を操作しトランザクションを制御する方法について説明します。


Understanding persistent and temporary database components
Understanding persistent and temporary database components1088002

Section topics 	参照

アプリケーション内の各データベース接続は，設計時にデータベース接続を明示的に提供するのであれ実行時にそれを動的に作成するのであれ，データベースコンポーネントによってカプセル化されます。アプリケーションがデータベースと接続しようとすると，明示的にインスタンス化されたつまり持続的なデータベースコンポーネントが使われるか，または一般に接続の存続期間中だけ存在する一時データベースコンポーネントが生成されます。

フォームやデータモジュールにアプリケーション自身のデータベースコンポーネントがない場合，必要に応じて一時的なデータベースコンポーネントが自動的に作成されます。一時データベースコンポーネントは，多くのデスクトップデータベースアプリケーションを幅広くサポートします。開発者がデータベース接続の詳細を処理する必要はありません。ただし，ほとんどのクライアント／サーバーアプリケーションでは，一時データベースコンポーネントに依存するのではなく，データベースコンポーネントを独自に作成すべきです。そうすればデータベースに対する制御が拡大し，以下のことが可能になります。

持続的なデータベース接続の作成

データベースサーバーへのログインのカスタマイズ

トランザクションの制御とトランザクション排他レベルの指定

アプリケーションにローカルな BDE エリアスの作成


Using temporary database components
Using temporary database components1088003

Section topics 	参照

一時データベースコンポーネントは，必要に応じて，Delphi によって自動的に生成されます。たとえば，TDatabase コンポーネントの配置と設定，およびそれへのテーブルコンポーネントの関連付けを行わなくても，Ttable コンポーネントをフォームに配置してそのプロパティを設定してテーブルを開くと，一時データベースコンポーネントが作成されます。

一時データベースコンポーネントの主なプロパティは，所属先のセッションによって決まります。たとえば，セッションの KeepConnections プロパティを制御することにより，関連するデータセットが閉じた場合にもデータベース接続を維持するのか（デフォルト），またはすべてのデータセットが閉じたら接続を切断するのかが決まります。同様に，セッションのデフォルトの OnPassword イベントにより，パスワードの必要なサーバー上のデータベースにアプリケーションが接続しようとしたときに標準のパスワード入力ダイアログボックスが表示されます。一時データベースコンポーネントのほかのプロパティは，ログインとトランザクションの標準処理に関係します。一時データベース接続に対するセッション制御とセッションについては，「データベースセッションの管理」の「セッションコンポーネントの操作」を参照してください。

一時データベースコンポーネント用に作成されるデフォルトの各プロパティは，広範な状況に対応する，一般的で適切な動作をします。ただし，多数のユーザーがいてデータベース接続の条件が異なる複雑なミッションクリティカルクライアント／サーバーアプリケーションについては，独自のデータベースコンポーネントを作成して，それぞれのデータベース接続をアプリケーションのニーズに合わせて調節しなければなりません。


Creating database components at design time
Creating database components at design time1088004

Section topics

コンポーネントパレットの［Data Access］ページには，データモジュールまたはフォームに追加できるデータベースコンポーネントがあります。設計時にデータベースコンポーネントを作成する一番の利点は，データベースコンポーネントの初期プロパティを設定でき，OnLogin イベントを記述できることです。OnLogin を使うと，データベースコンポーネントが最初にサーバーに接続するときに，データベースサーバーのセキュリティ処理をカスタマイズできます。接続プロパティの管理については，「データベースサーバーへの接続」を参照してください。サーバーセキュリティについては，「サーバーログインの制御」を参照してください。


Creating database components at run time
Creating database components at run time1088005

Section topics 	参照

データベースコンポーネントは実行時に動的に作成できます。実行時に必要になるデータベースコンポーネント数が不明の場合や，アプリケーションで明示的にデータベース接続を制御しなければならない場合などに，アプリケーションでこの作成を実行します。実際には，必要であれば実行時に一時データベースコンポーネントが Delphi 自身によって作成されています。データベースコンポーネントを実行時に開発者が作成する場合は，データベースコンポーネントにユニークな名前を付け，それをセッションに関連付けなければなりません。

コンポーネントを作成するには，TDatabase.Create コンストラクタを呼び出します。次の関数は，データベース名とセッション名の 2 つを受け取ると，データベースコンポーネントを実行時に作成して，（必要であれば新しいセッションを作成して）指定されたセッションにそのコンポーネントを関連付け，いくつかの主なデータベースコンポーネントプロパティを設定します。

function RunTimeDbCreate(const DatabaseName, SessionName: string): TDatabase;

var

TempDatabase: TDatabase;

begin

TempDatabase := nil;

try

{ セッションがあればアクティブにする。なければ新しいセッションを作成する }

Sessions.OpenSession(SessionName);

with Sessions do

with FindSession(SessionName) do

Result := FindDatabase(DatabaseName);

if Result = nil then

begin

{ 新しいデータベースコンポーネントを作成する }

TempDatabase := TDatabase.Create(Self);

TempDatabase.DatabaseName := DatabaseName;

TempDatabase.SessionName := SessionName;

TempDatabase.KeepConnection := True;

end;

Result := OpenDatabase(DatabaseName);

end;

end;

except

TempDatabase.Free;

raise;

end;

end;

次のコードは，この関数を呼び出して，実行時にデフォルトセッションのデータベースコンポーネントを作成する方法を示しています。

var

MyDatabase: array [1..10] of TDatabase;

MyDbCount: Integer;

begin

{ MyDbCount を先に初期化する }

MyDbCount := 1;

...

{ その後，実行時にデータベースコンポーネントを作成する }

begin

MyDatabase[MyDbCount] := RunTimeDbCreate('MyDb' + IntToStr(MyDbCount), '');

Inc(MyDbCount);

end;

...

end;


Controlling connections
Controlling connections1088006

Section topics 	参照

データベースコンポーネントを設計時に作成する場合でも実行時に作成する場合でも，TDatabase のプロパティ，イベント，メソッドを使ってアプリケーションでのその動作を制御したり変更できます。以降の各節では，データベースコンポーネントの操作方法について説明します。TDatabase のすべてのプロパティ，イベント，メソッドについては，オブジェクトおよびコンポーネントライブラリについては，オンラインヘルプを参照してください。


Associating a database component with a session
Associating a database component with a session1088007

Section topics 	参照

すべてのデータベースコンポーネントは BDE セッションと関連付けなければなりません。2 つのデータベースコンポーネントプロパティ Session と SessionName とがこの関連付けを確立します。

SessionName は，データベースコンポーネントを関連付ける先のセッションエリアスを表します。設計時にデータベースコンポーネントを初めて作成すると，SessionName は「Default」に設定されます。マルチスレッドの BDE アプリケーションや再入可能な BDE アプリケーションは複数のセッションを持つことがあります。設計時にオブジェクトインスペクタのドロップダウンリストから有効な SessionName を選択できます。このドロップダウンリストには，アプリケーション内の各セッションコンポーネントの SessionName プロパティの値が表示されます。

Session プロパティは実行時の読み出し専用プロパティで，SessionName プロパティが指定するセッションコンポーネントを指します。たとえば，SessionName が空白または「Default」の場合，Session プロパティは，グローバルの Session 変数が参照しているのと同じ TSession インスタンスを参照します。Session を使うと，アプリケーションはセッションの実際の名前を知らずにデータベースコンポーネントの親セッションコンポーネントのプロパティ，メソッド，イベントにアクセスできます。これは，データベースコンポーネントを実行時に別のセッションに割り当てるときに便利です。

BDE セッションについては，「データベースセッションの管理」を参照してください。


Specifying a BDE alias
Specifying a BDE alias1088008

Section topics 	参照

AliasName と DriverName は，BDE 固有の相互に排他的なプロパティです。AliasName は，データベースコンポーネントに使う既存の BDE エリアスの名前を表します。BDE エリアスは，特定のデータベースコンポーネントにデータセットコンポーネントをリンクできるように，データセットコンポーネント用の以後のドロップダウンリストに表示されます。ドライバ名は BDE エリアスの一部なので，データベースコンポーネントに AliasName を指定すると，すでに DriverName に代入されている値はクリアされます。

メモ	BDE エリアスの作成と編集にはデータベースエクスプローラまたは BDE Administrator を使います。BDE エリアスの作成と管理については，「BDE エリアスの操作」を参照してください。

DatabaseName を使うと，データベースコンポーネントにアプリケーション固有の名前を付けられます。指定する名前は，AliasName または DriverName とは別の名前であり，アプリケーションに対してローカルになります。DatabaseName は BDE エリアス名であったり，Paradox や dBASE のファイルの場合は絶対パス名であったりします。AliasName と同様に，DatabaseName はデータセットコンポーネント用のドロップダウンリストに表示され，データセットコンポーネントとデータベースコンポーネントのリンクに使用されます。

DriverName は BDE ドライバの名前です。ドライバ名は BDE エリアスの 1 パラメータですが，DatabaseName プロパティを使ってデータベースコンポーネントのローカル BDE エリアスを作成するときにエリアスのかわりにドライバ名を指定できます。指定したドライバ名と，AliasName に指定されている BDE エリアスの一部であるドライバ名との間に生じるかもしれない衝突を防ぐため，DriverName を指定すると，すでに AliasName に代入されている値はクリアされます。

設計時に BDE エリアスの指定，BDE ドライバの割り当て，ローカル BDE エリアスの作成をするには，データベースコンポーネントをダブルクリックしてデータベースプロパティエディタを起動します。

プロパティエディタの［名前(N)］編集ボックスにデータベース名を入力します。Alias プロパティ用の［エリアス名(A)］コンボボックスには，既存の BDE エリアス名を入力するかまたはドロップダウンリストの既存のエリアスを選択します。DriverName プロパティ用の［ドライバ名(D)］コンボボックスには，既存の BDE ドライバ名を入力するかまたはドロップダウンリストの既存のドライバ名を選択します。

メモ	データベースプロパティエディタでは，BDE の接続パラメータを表示および設定したり，LoginPrompt プロパティと KeepConnection プロパティの状態を設定することもできます。接続パラメータの操作については，「BDE エリアスのパラメータの設定」を参照してください。LoginPrompt の状態の設定については，「サーバーログインの制御」を参照してください。KeepConnection の設定については，「データベースサーバーへの接続」を参照してください。

DatabaseName，AliasName，DriverName を実行時に設定するには，適切な代入文をコードに記述します。たとえば次のコードは，編集ボックスのテキストを使って，データベースコンポーネント Database1 のローカルエリアスを作成します。

Database1.DatabaseName := Edit1.Text;


Setting BDE alias parameters
Setting BDE alias parameters1088009

Section topics 	参照

設計時には，以下の 3 通りの方法で接続パラメータを作成または編集できます。

データベースエクスプローラまたは BDE Administrator を使って BDE エリアスとパラメータを作成または修正する（各ユーティリティについては，オンラインヘルプを参照）

オブジェクトインスペクタの中で Params プロパティをダブルクリックして文字列リストエディタを起動する（文字列リストエディタについては，『ユーザーズガイド』を参照）

データモジュールまたはフォームの中でデータベースコンポーネントをダブルクリックしてデータベースプロパティエディタを起動する

これらの方法はすべて，データベースコンポーネントの Params プロパティを編集します。Params は，データベースコンポーネントに関連付けられた BDE エリアスのデータベース接続パラメータの文字列リストです。通常の接続パラメータには，パス名，サーバー名，スキーマキャッシングサイズ，言語ドライバ，SQL 問い合わせモードなどがあります。

データベースプロパティエディタを初めて起動したとき，BDE エリアスのパラメータは表示されません。現在の設定を表示するには，［デフォルト(E)］をクリックします。［パラメータの変更(P)］メモボックスに現在のパラメータが表示されます。既存のエントリを編集したり，新しいエントリを追加できます。既存のパラメータをクリアするには，［クリア(C)］をクリックします。［OK］をクリックすると変更が有効になります。

実行時にアプリケーションがエリアスパラメータを設定するには，Params プロパティを直接編集しなければなりません。


Controlling server login
Controlling server login1088010

Section topics 	参照

ほとんどのリモートデータベースサーバーには，権限のないアクセスを禁止するセキュリティ機能があります。一般にサーバーは，データベースへのアクセスを許可する前にユーザー名とパスワードのログインを要求してきます。

サーバーがログインを要求する場合，設計時には，データベースへの接続を最初に試みたときに標準の［データベースへのログイン］ダイアログボックスが表示され，ユーザー名とパスワードの入力が求められます。

実行時には，以下の方法でサーバーのログイン要求を処理できます。

データベースコンポーネントの LoginPrompt プロパティを True（デフォルト）に設定する。サーバーがユーザー名とパスワードを要求すると，標準の［データベースへのログイン］ダイアログボックスが表示されます。

LoginPrompt プロパティを False に設定して，データベースコンポーネントの Params プロパティに USER NAME と PASSWORD の 2 つのパラメータを直接記述する。

USER NAME=SYSDBA

PASSWORD=masterkey

重要	パスワードを含んだ Params プロパティは簡単に覗くことができます。サーバーのセキュリティ上問題となるため，この方法はできるだけ使わないでください。

データベースコンポーネントの OnLogin イベントを記述し，それを使って実行時にログインパラメータを設定する。OnLogin では，データベースコンポーネントの Params プロパティの複製が渡され，それを修正することができる。Params プロパティの複製は LoginParams として参照することができる。ログインパラメータを設定または変更するには，次のように Values プロパティを使う

LoginParams.Values['USER NAME'] := UserName;

LoginParams.Values['PASSWORD'] := PasswordSearch(UserName);

OnLogin イベントの終了時に LoginParams の値が OnLogin から Params に渡され，接続の確立に使われる


Connecting to a database server
Connecting to a database server1088011

Section topics 	参照

データベースコンポーネントを使ってデータベースサーバーに接続するには以下の 2 通りの方法があります。

Open メソッドを呼び出す

Connected プロパティを True に設定する

Connected を True に設定すると，Open メソッドが実行されます。Open は，DatabaseName プロパティまたは Directory プロパティで指定されたデータベースがあることを確認して，そのデータベースコンポーネントの OnLogin イベントがあれば，それを実行します。なければ，デフォルトの［データベースへのログイン］ダイアログボックスを表示します。

メモ	データベースコンポーネントがサーバーへ接続されないときにアプリケーションがそのデータベースコンポーネントに関連付けられたデータセットを開こうとすると，そのデータベースコンポーネントの Open メソッドがまず呼び出され接続が確立します。データセットが既存のデータベースコンポーネントと関連付けられていない場合は，一時データベースコンポーネントが作成され接続の確立に使われます。

いったん確立したデータベース接続は，アクティブなデータセットが少なくとも 1 つある限りは維持されます。アクティブなデータセットがなくなったときに接続を切断するかどうかは，データベースコンポーネントの KeepConnection プロパティの設定によって決まります。

KeepConnection は，データベースに関連付けられているすべてのデータセットが閉じた場合にもアプリケーションがそのデータベースとの接続を維持するかどうかを表します。True ならば，接続が維持されます。リモートデータベースサーバーへ接続する場合，またはデータセットを頻繁に開いたり閉じたりするアプリケーションの場合は，ネットワークトラフィックを減らしてアプリケーションを速くするために，KeepConnection を True に設定しておいてください。False ならば，データベースを使っているアクティブなデータセットがなくなると接続が切断されます。データベースを使うデータセットを後で開いた場合は，接続を再度確立して初期化しなければなりません。


Special considerations when connecting to a remote server
Special considerations when connecting to a remote server1088012

Section topics 	参照

Delphi アプリケーションでリモートデータベースサーバーに接続する場合，アプリケーションは，BDE と Borland SQL Link ドライバを使って接続を確立します（BDE は指定された ODBC ドライバとも通信できます）。接続する前に，SQL Link ドライバまたは ODBC ドライバをアプリケーション用に設定しなければなりません。SQL Link と ODBC の各パラメータは，データベースコンポーネントの Params プロパティに格納されます。SQL Link のパラメータについては，オンラインヘルプの SQLLNK32.HLP を参照してください。Params プロパティについては，「BDE エリアスのパラメータの設定」を参照してください。

Working with network protocols1088013

SQL Link ドライバまたは ODBC ドライバを適切に設定する一環として，サーバーで使われるネットワークプロトコル（SPX/IPX や TCP/IP など）を指定しなければなりません。ほとんどの場合，プロトコルの環境設定は，サーバーのクライアントセットアップソフトウェアを使用して行われます。ODBC の場合は，ODBC ドライバマネージャを使って設定内容をチェックする必要があります。

サーバーとクライアント間の初期接続の確立には，問題が生じる場合があります。問題がある場合は，次のチェックリストをトラブルシューティングに役立ててください。

サーバークライアント側の接続が適切に設定されているか？

TCP/IP を使っている場合

TCP/IP 通信ソフトウェアをインストールしてあるか，また適切な WINSOCK.DLL をインストールしてあるか？

クライアントの HOSTS ファイルにサーバーの IP アドレスを登録してあるか？

ドメインネームサービス（DNS）を適切に設定してあるか？

サーバーの PING が可能か？

接続のための DLL とデータベースドライバに検索パスが通っているか？

トラブルシューティングについては，SQL Link のオンラインヘルプおよび各サーバーのマニュアルを参照してください。

Using ODBC1088014

Delphi アプリケーションでは，DB2，Btrieve，Microsoft Access などの ODBC データソースを使えます。ODBC ドライバ接続には，以下の 3 つが必要です。

ベンダー提供の ODBC ドライバ

Microsoft ODBC ドライバマネージャ

BDE 環境設定ユーティリティ

ODBC ドライバ接続の BDE エリアスの設定には，BDE Administrator を使います。詳細については，オンラインヘルプを参照してください。


Disconnecting from a database server
Disconnecting from a database server1088015

Section topics 	参照

データベースコンポーネントでサーバーから切断するには以下の 2 通りの方法があります。

Connected プロパティを False に設定する

Close メソッドを呼び出す

Connected を False に設定すると，Close メソッドが呼び出されます。Close は，開いているすべてのデータセットを閉じてサーバーから切断します。たとえば次のコードは，データベースコンポーネントのアクティブなすべてのデータセットを閉じ，接続を切断します。

Database1.Connected := False;

メモ	Close は KeepConnection が True の場合でもデータベースサーバーから切断します。


Closing datasets without disconnecting from a server
Closing datasets without disconnecting from a server1088016

Section topics 	参照

すべてのデータセットを閉じるだけでデータベースサーバーからの接続は切断したくないことがあります。

サーバーから切断せずに開いているすべてのデータセットを閉じる手順は次のとおりです。

1.	データベースコンポーネントの KeepConnections プロパティを True に設定します。

2.	データベースコンポーネントの CloseDataSets メソッドを呼び出します。


Iterating through a database component's datasets
Iterating through a database component's datasets1088017

Section topics 	参照

データベースコンポーネントには，それに関連付けられたすべてのデータセットをアプリケーションが巡回できるようにする 2 つのプロパティ DataSets と DataSetCount があります。

DataSets は，データベースコンポーネントのアクティブなすべてのデータセット（TTable，TQuery，TStoredProc）の添字付き配列です。アクティブなデータセットとは，現在開いているデータセットです。DataSetCount は，現在のアクティブなデータセット数を表す読み出し専用の整数値です。

DataSetCount と一緒に DataSets を使うと，現在アクティブなすべてのデータセットをコードの中で巡回できます。たとえば次のコードは，アクティブなすべてのデータセットを巡回して，TTable 型のデータセットの CachedUpdates を True に設定します。

var

I: Integer;

begin

for I := 0 to DataSetCount - 1 do

if DataSets[I] is TTable then

DataSets[I].CachedUpdates := True;

end;


Handling transactions
Handling transactions1088018

Section topics 	参照

Delphi を使ってデータベースアプリケーションを作成する場合，ローカルの Paradox テーブルや dBASE テーブルも含め，すべてのデータベースアクセスについてトランザクションを制御できます。トランザクションはアクションのグループであり，そのすべてのアクションは，データベース内の 1 つまたは複数のコミット（確定）前のテーブルに対して正常に実行されなければなりません。グループ内のアクションが 1 つでも失敗すると，すべてのアクションはロールバックされ（取り消され）ます。

ハードウェア障害があっても，トランザクションによってデータベースの一貫性が保証されます。マルチユーザーの同時アクセスを許しながら，データの整合性も保ちます。

たとえば，ある商品の注文を受けたことを示すためにアプリケーションで ORDERS テーブルを更新し，次に在庫の減少を示すために INVENTORY テーブルを更新する場合を考えます。ORDERS テーブルを更新した後で INVENTORY テーブルを更新する前にハードウェア障害があると，受けた注文が在庫に反映されず，データベースは一貫性を失います。トランザクション制御の下では，両方の文が同時にコミットされます。一方の文が失敗した場合，両方ともロールバックされます。


Using implicit transactions
Using implicit transactions1088019

Section topics 	参照

デフォルトでは，ボーランドデータベースエンジン（BDE）を通じて暗黙のトランザクション制御がアプリケーションに提供されます。アプリケーションが暗黙のトランザクション制御の下にある場合，基になったデータベースに書き込まれるデータセットのレコードごとに別々のトランザクションが使われます。Post や AppendRecord などの書き込み処理は，個別にコミットされます。

暗黙のトランザクション制御を使うとレコード更新の衝突が最小限になり，データベースのビューの一貫性が保証されます。しかし，データベースへの各データ行の書き込みがそれぞれのトランザクション内で行われるため，ネットワークトラフィックが過大になったり，アプリケーションの処理効率が低下することがあります。

明示的なトランザクション制御では，トランザクションを開始，コミット，ロールバックするのにもっとも効果的なタイミングを選択できます。マルチユーザー環境でのクライアントアプリケーションを開発する場合，Sybase，Oracle，Microsoft SQL，InterBase などのリモート SQL サーバーや ODBC 準拠のリモートデータベースに対して実行するアプリケーションでは特に，トランザクションを明示的に制御する必要があります。

メモ	キャッシュアップデートを使うと，アプリケーション内で使わなければならないトランザクションの数を最小限にできる場合があります。キャッシュアップデートについては，「キャッシュアップデートの操作」を参照してください。


Working with explicit transaction control
Working with explicit transaction control1088020

Section topics 	参照

Delphi データベースアプリケーションでは，以下の 2 通りのどちらかの方法でトランザクションを明示的に制御できます。

StartTransaction，Commit，Rollback，InTransaction，TransIsolation などのデータベースコンポーネントのメソッドとプロパティを使う

TQuery コンポーネントのパススルー SQL を使う。パススルー SQL は Delphi Client/Server Suite でしか意味を持たない。Delphi Client/Server Suite では，SQL Link を使ってリモートの SQL サーバーまたは ODBC サーバーに SQL 文を直接渡す。TQuery については，「問い合わせの操作」を参照

トランザクション制御にデータベースコンポーネントのメソッドとプロパティを使う一番の利点は，特定のデータベースまたはサーバーに依存しない，簡潔で移植性のあるアプリケーションを作成できることです。

パススルー SQL を使う一番の利点は，スキーマキャッシングなど，特定のデータベースサーバーの高度なトランザクション管理機能を使えることです。サーバーのトランザクション管理モデルの利点については，各データベースサーバーのマニュアルを参照してください。

Starting a transaction1088021

トランザクションを開始すると，その後でデータベースを読み書きするすべての文は，そのトランザクションのコンテキストで実行されます。それぞれの文はグループの一部とみなされます。変更がデータベースに正常にコミットされなければ，変更はすべて元に戻されます。

文のグループ化は，文がほかの文に依存する場合に便利です。自動預金支払い機（ATM）での銀行取り引きについて考えてみます。普通預金口座から当座預金口座に預金を移す場合，銀行のデータベースレコードに以下の 2 つの変更が必要です。

1.	普通預金口座への借方の記入

2.	当座預金口座への貸方の記入

なんらかの理由で一方のアクションを完了できない場合，どちらのアクションも発生してはいけません。2 つのアクションは密接に関連しているので，単一のトランザクションで発生しなければなりません。

Delphi アプリケーションでトランザクションを開始するには，データベースコンポーネントの StartTransaction メソッドを次のように呼び出します。

DatabaseInterBase.StartTransaction;

これ以降のすべてのデータベースアクションは，Commit または Rollback を次に呼び出してトランザクションを明示的に終了するまで，新しく開始したトランザクションのコンテキストで発生します。

トランザクションは必要最小限にすることが理想です。トランザクションがアクティブな時間が長くなるほど，そのデータベースに同時にアクセスするユーザーが増え，トランザクションの存続期間中に並行して開始および終了する同時トランザクションが多くなり，変更をコミットしようとするときに別のトランザクションと衝突する可能性が高くなります。

Committing a transaction1088022

データベースの変更を確定するには，データベースコンポーネントの Commit メソッドを使ってトランザクションをコミットしなければなりません。コミット文を実行すると，データベースの変更が保存され，トランザクションが終了します。たとえば，次の文は前述のコード例で開始したトランザクションを終了します。

DatabaseInterBase.Commit;

メモ	Commit は必ず try...except 文の中で使うようにしてください。トランザクションを正常にコミットできない場合は，エラー処理を試行し，さらに操作を再試行できます。

Rolling back a transaction1088023

データベースの変更を破棄するには，Rollback を使ってトランザクションでデータベースの変更をロールバックしなければなりません。Rollback はトランザクションによる変更を元に戻し，トランザクションを終了します。たとえば，次の文はトランザクションをロールバックします。

DatabaseInterBase.Rollback;

通常，Rollback は以下の 2 種類のコードの中で使います。

例外処理コード（データベースのエラーを回復できないとき）

ボタンまたはメニューのイベントコード（ユーザーが［キャンセル］ボタンをクリックした場合など）

Using the TransIsolation property1088024

TransIsolation は，データベースコンポーネントのトランザクションの排他レベルの指定に使います。トランザクション排他レベルは，同一のテーブルを操作する同時トランザクション間の対話方式を指定するものです。特に，ほかのトランザクションによるテーブルの変更の認識に影響します。TransIsolation を変更または設定する前に，Delphi のトランザクションとトランザクション管理についての知識が必要です。

TransIsolation のデフォルト設定は，tiReadCommitted です。表に TransIsolation の値とその意味を示します。

排他レベル	意味
tiDirtyRead	ほかの同時トランザクションによってデータベースに加えられた，コミット（確定）されていない変更の読み出しを許す。コミットされていない変更は，いつでもロールバックできる（元に戻せる）。これは最も低い排他レベルである
tiReadCommitted	ほかの同時トランザクションによってコミット（確定）されたデータベースの変更だけ読み出せるようにする。これがデフォルトの排他レベルである
tiRepeatableRead	データベースの読み出しを一度に 1 つだけ許す。以後，ほかの同時トランザクションによるデータの変更をトランザクションは認識できない。この排他レベルでは，トランザクションがいったんレコードを読み出すと，そのレコードのビューが変化しないことが保証される。これは最も高い排他レベルである
データベースサーバーによっては，排他レベルのサポートが異なる場合や，まったくサポートされない場合があります。要求した排他レベルをサーバーがサポートしていない場合は，次に高い排他レベルが使われます。表に各種のサーバーで実際に使われている排他レベルを示します。排他レベルについては，各サーバーのマニュアルを参照してください。

サーバー	指定されたレベル	実際のレベル
Oracle	tiDirtyRead tiReadCommitted tiRepeatableRead	tiReadCommitted tiReadCommitted tiRepeatableRead（読み出し専用）
Sybase，MS-SQL	tiDirtyRead tiReadCommitted tiRepeatableRead	tiReadCommitted tiReadCommitted 未サポート
DB2	tiDirtyRead tiReadCommitted tiRepeatableRead	tiDirtyRead tiReadCommitted tiRepeatableRead
Informix	tiDirtyRead tiReadCommitted tiRepeatableRead	tiDirtyRead tiReadCommitted tiRepeatableRead
InterBase	tiDirtyRead tiReadCommitted tiRepeatableRead	tiReadCommitted tiReadCommitted tiRepeatableRead
Paradox，dBASE，Access，FoxPro	tiDirtyRead tiReadCommitted tiRepeatableRead	tiDirtyRead 未サポート 未サポート
メモ	ローカルの Paradox，dBASE，Access，FoxPro のテーブルでトランザクションを使う場合，TransIsolation はデフォルトの tiReadCommitted ではなく tiDirtyRead に設定してください。ローカルテーブルで TransIsolation が tiDirtyRead 以外に設定されると BDE エラーが返されます。

排他が ODBC を使ってサーバーとのインターフェースを取る場合，ODBC ドライバも排他レベルをサポートしている必要があります。詳細については，ODBC ドライバのマニュアルを参照してください。


Using passthrough SQL
Using passthrough SQL1088025

Section topics 	参照

トランザクションを制御するためにパススルー SQL を使うための必要条件を以下に示します。

Delphi Client/Server Suite を使う

適切な SQL Link ドライバをインストールする。デフォルトインストールを選択して Delphi をインストールした場合，すべての SQL Link ドライバがすでに正しくインストールされている

ネットワークプロトコルを正しく設定する。詳細については，ネットワーク管理者に問い合わせてください。

リモートサーバーのデータベースにアクセスする。

SQL Explorer を使って SQLPASSTHROUMODE を NOT SHARED に設定する。

パススルー SQL を使ってリモートデータベースサーバーに SQL トランザクション制御文を直接送信するには，TQuery，TStoredProc，TUpdateSQL のいずれかのコンポーネントを使います。BDE は SQL 文を処理しません。パススルー SQL を使うと，サーバーのトランザクション制御が標準でない場合は特に，それらのトランザクション制御の利点を直接利用できます。

Setting SQLPASSTHRU MODE1088026

SQLPASSTHRUMODE には，BDE とパススルー SQL 文が同一のデータベース接続を共有できるかどうかを指定します。ほとんどの場合，SQLPASSTHRUMODE は SHARED AUTOCOMMIT に設定されます。ただし，SQL トランザクション制御文をサーバーに渡したい場合は，SQL Explorer を使って SQLPASSTHRUMODE を NOT SHARED に設定しなければなりません。SQLPASSTHRUMODE については，BDE Administrator のオンラインヘルプを参照してください。

メモ	SQLPASSTHRUMODE が NOT SHARED の場合は，SQL トランザクション文をサーバーに渡す TQuery コンポーネントと，渡さないその他のデータセットコンポーネントに，それぞれ別のデータベースコンポーネントを使わなければなりません。


Using local transactions
Using local transactions1088027

Section topics 	参照

BDE は Paradox テーブルや dBASE テーブルに対するローカルトランザクションをサポートしています。コーディングの面では，ローカルトランザクションでもリモートデータベースサーバーにあるトランザクションでも違いはありません。

ローカルテーブルに対してトランザクションを開始すると，そのテーブルに対して実行された更新がログに記録されます。ログの各レコードには，レコードの以前のレコードバッファが記録されます。トランザクションがアクティブな場合，更新されるレコードは，そのトランザクションがコミットされるかロールバックされるまでロックされます。ロールバック時には，更新したレコードに対して以前のレコードバッファが使われ，レコードが更新前の状態に復元されます。

Understanding the limitations of local transactions1088028

ローカルトランザクションには以下の制限があります。

クラッシュの自動復元はない

データ定義文はサポートされていない

Paradox の場合，ローカルトランザクションを実行できるのは，有効なインデックスがあるテーブルに対してだけである。インデックスがない Paradox テーブルでは，データをロールバックできない

一時テーブルに対してはトランザクションを実行できない

BDE ASCII ドライバに対してはトランザクションを実行できない

TransIsolation レベルは tiDirtyRead 以外に設定してはならない

トランザクション中にテーブル上でカーソルを閉じると，以下の場合を除いて，トランザクションはロールバックされる

複数のテーブルを開いているとき

変更しなかったテーブル上でカーソルを閉じるとき


Applying cached updates for multiple datasets
Applying cached updates for multiple datasets1088029

Section topics 	参照

アプリケーションでキャッシュアップデートを使う場合，通常はデータセットレベルでキャッシュアップデートを操作します。ただし，データベースコンポーネントには，データセットそれぞれの ApplyUpdates メソッドを個別に呼び出すかわりに，指定されたデータセットコンポーネント集合に対してキャッシュアップデートを適用できる ApplyUpdates メソッドがあります。

ApplyUpdates で使うパラメータは 1 つで，更新するデータセットの配列を示します。たとえば，次の文はデータベースコンポーネントに関連付けられた 2 つのデータセットに対してキャッシュアップデートを適用します。

Database1.ApplyUpdates([DataSet1, DataSet2];

このメソッドは，データベーストランザクションを開始して，キャッシュされている更新レコードをデータベースサーバーに書き込みます。キャッシュアップデートの適用では，以下の 2 段階の処理が行われます。

1.	データベーストランザクションを開始する

2.	キャッシュされている更新レコードがデータベースに書き込まれる（第 1 段階）

データベースの書き込みに成功すると，以下の段階に移行します。

1. データベースの変更がコミットされ，トランザクションが終了する

2. キャッシュアップデートがコミットされ，内部キャッシュバッファがクリアされる（第 2 段階）

データベースの書き込みに失敗すると，変更がロールバックされ，トランザクションが終了するが，キャッシュはクリアされない

この 2 段階の処理により，たとえば，マスターリンクフォームでのデータセットなど，複数の相互に関係するデータセットを更新する場合のエラーからの回復が簡単に行えます。

キャッシュアップデートの使い方についての詳細は，「キャッシュアップデートの操作」を参照してください。


Understanding database and session component interactions
Understanding database and session component interactions1088030

Section topics 	参照

一般に，KeepConnections などのセッションコンポーネントの各プロパティにはグローバルなデフォルトの動作があり，実行時に必要に応じて自動的に作成されるすべての一時データベースコンポーネントに，その動作が適用されます。

セッションメソッドの使われ方はやや異なります。TSession のメソッドは，データベースコンポーネントの状態にかかわらず，すべてのデータベースコンポーネントに対して作用します。たとえば，セッションメソッド DropConnections は，セッションのデータベースコンポーネントに属するすべてのデータセットを閉じ，個々のデータベースコンポーネントの KeepConnection プロパティが True であっても，すべてのデータベース接続を切断します。

データベースコンポーネントのメソッドは，特定のデータベースコンポーネントに関連付けられているデータセットに対してだけ適用されます。たとえば，データベースコンポーネント Database1 がデフォルトセッションに関連付けられているとします。Database1.CloseDataSets は，Database1 に関連付けられたデータセットだけを閉じます。デフォルトセッション内でほかのデータベースコンポーネントに属して開いているデータセットは，開いたままになります。


Using database components in data modules
Using database components in data modules1088031

Section topics 	参照

データベースコンポーネントはデータモジュールに問題なく追加できます。ただし，データベースコンポーネントがあるデータモジュールをオブジェクトリポジトリに入れた場合，および他のユーザーがこれらのデータモジュールから継承できるようにしたい場合は，データベースコンポーネントの HandleShared プロパティを True に設定してください。


See also1088032

TDatabase

データアクセスコンポーネント

データモジュールの使い方


Understanding datasets
Understanding datasets1089001

Section topics 	参照

Delphiからデータにアクセスする場合，データセットと，そのグループを基本とします。アプリケーションはどのデータベースにアクセスするときもデータセットを使います。通常，データセットオブジェクトはデータベース固有のテーブルを表します。データベースにアクセスする問い合わせやストアドプロシージャを表すこともあります。

データベースアプリケーションでは，仮想データセットオブジェクト TDataSet から派生したデータセットオブジェクトを使います。これらのオブジェクトは TDataSet からデータ項目，プロパティ，イベント，メソッドを継承しています。この章では，データベースアプリケーションで使うデータセットオブジェクトが継承する TDataSet の機能について説明します。どのデータセットオブジェクトを使うにも，この共通の機能を理解している必要があります。

次の図は，Delphi データセットコンポーネントの階層関係を表しています。

Delphi dataset hierarchy1089002

すべてのデータセットオブジェクトに共通の概念を理解し，ボーランドデータベースエンジン（BDE）を使わないカスタムデータセットオブジェクトを開発したい場合は，この章に目を通してください。

ボーランドデータベースエンジン（BDE）を使う従来の 2 階層のクライアント／サーバーデータベースアプリケーションを開発する場合は，「BDE 対応データセットについて」を参照してください。TBDEDataSet と TDBDataSet について説明しているほか，すべてのデータベースアプリケーションで一般的に使われているデータセットコンポーネント TQuery，TStoredProc，Ttable に共通の機能についても詳細に説明しています。

Delphi Client/Server または Delphi Enterprise を使っている場合は，分散データセットを使って多層のデータベースアプリケーションを開発できます。多層のクライアントデータセットについては，「マルチ階層アプリケーションの作成」を参照してください。TClientDataSet の使い方や，アプリケーションサーバーへのクライアントの接続方法を説明しています。


What is TDataSet?
What is TDataSet?1089003

Section topics 	参照

TDataSet はアプリケーションで使うすべてのデータセットオブジェクトの上位にあります。すべてのデータセットオブジェクトが共有するデータ項目，プロパティ，イベント，メソッドを定義しています。TDataSet は仮想データセットです。つまり，そのプロパティやメソッドの多くは仮想または抽象として宣言されます。抽象メソッドは，実際の実装がない関数または手続きの宣言です。この宣言は，すべての下位データセットオブジェクトに実装しなければならないが，実装方法はそれらのオブジェクトごとに異なるメソッド（およびそのパラメータと戻り型）を記述するプロトタイプです。仮想メソッドは抽象メソッドとは異なりますが，関数または手続きの宣言です。このメソッドは下位オブジェクトでオーバーライドすることで実装できます（通常はオーバーライドされます）。

TDataSet には抽象メソッドがあるので，アプリケーションで直接使うと実行時エラーになります。かわりに，TDataSet の下位オブジェクト（TTable，TQuery，TStoredProc など）のインスタンスを作成してアプリケーションで使うか，TDataSet またはその下位オブジェクトから自分のデータセットオブジェクトを派生させてからそのすべての抽象メソッドの実装を記述します。

とはいえ，TDataSet はすべてのデータセットオブジェクトに共通する機能をいくつも定義しています。たとえば，すべてのデータセットの基本構造，1 つまたは複数のデータベーステーブルの実際の列に対応した TField コンポーネントの配列，アプリケーションが提供する参照項目または計算項目などを定義しています。TField コンポーネントの詳細については，「項目の操作」を参照してください。

この章では，すべてのデータセットオブジェクトに共通する以下の TDataSet 機能について説明します。

データセットを開く／閉じる

データセットの状態の決定と設定

レコード間の移動

レコードの検索

データセットのフィルタ処理

レコードの編集と変更


Opening and closing datasets
Opening and closing datasets1089004

Section topics 	参照

テーブルや問い合わせを使ってデータの読み書きをするには，まずアプリケーションでデータセットを開かなければなりません。データセットを開くには，以下の 2 通りの方法があります。

設計時にオブジェクトインスペクタを使うか，実行時にコードによって，データセットの Active プロパティを True に設定する

CustTable.Active := True;

実行時にデータセットの Open メソッドを呼び出す

CustQuery.Open;

データセットを閉じるには，以下の 2 通りの方法があります。

設計時にオブジェクトインスペクタを使うか，実行時にコードによって，データセットの Active プロパティを False に設定する

CustQuery.Active := False;

実行時にデータセットの Close メソッドを呼び出す

CustTable.Close;

TTable コンポーネントの TableName などのプロパティを変更したい場合は，そのデータセットを閉じる必要があります。実行時には，アプリケーションに固有のほかの理由でデータセットを閉じたい場合もあります。


Determining and setting dataset states
Determining and setting dataset states1089005

Section topics 	参照

データセットの状態（モード）によって，データセットのデータに対して何ができるかが決まります。たとえばデータセットが閉じた場合，その状態は dsInactive になり，そのデータに対して何もできないことが示されます。データセットは常にある 1 つの状態にあります。実行時にデータセットの State 読み出し専用プロパティを調べれば，データセットの現在の状態がわかります。表に State プロパティの値とその意味を示します。

値	State	意味
dsInactive	Inactive	非アクティブ状態。データセットは閉じている。データは使えない
dsBrowse	Browse	参照状態。データセットは開いている。データの取得はできるが，変更はできない。開いているデータセットのデフォルト状態である
dsEdit	Edit	編集状態。データセットは開いている。現在の行を変更できる
dsInsert	Insert	挿入状態。データセットは開いている。新しい行が挿入された
dsSetKey	SetKey	TTable と TClientDataSet にのみ適用される。データセットは開いている。インデックス付きの項目を基準に行の検索ができる。あるいは，SetRange 動作が進行中であることを示す。取得できるデータは限られており，データの変更はできない
dsCalcFields	CalcFields	データセットは開いている。OnCalcFields イベントが進行中であることを示す。計算項目以外の項目の変更を防止する
dsCurValue	CurValue	内部使用
dsNewValue	NewValue	内部使用
dsOldValue	OldValue	内部使用
dsFilter	Filter	データセットは開いている。フィルタが動作中であることを示す。取得できるデータは限られており，データの変更はできない
アプリケーションがデータセットを開くと，データセットは自動的に dsBrowse モードになります。データセットの状態はアプリケーションのデータ処理の状況に応じて変わります。開いているデータセットは以下のいずれかに基づいてその状態を変えます。

アプリケーションのコード

Delphi の組み込み動作

データセットを dsBrowse，dsEdit，dsInsert，dsSetKey の各状態にするには，状態の名前に対応するメソッドを呼び出します。たとえば次のコードは，CustTable を dsInsert 状態にし，ユーザーが入力した新しいレコードを受け付け，そのレコードをデータベースに書き込みます。

CustTable.Insert;	{データセットの状態を明示的に挿入状態にする}

AddressPromptDialog.ShowModal;

if AddressPromptDialog.ModalResult := mrOK then

CustTable.Post	{正常終了のときにデータセットの状態を参照状態にする}

else

CustTable.Cancel;	{取り消しのときにデータセットの状態を参照状態にする}

この例では，Delphi が以下の場合に自動的にデータセットの状態を dsBrowse に設定することがわかります。

Post メソッドがレコードのデータベース登録に成功した場合（Post が失敗した場合，データベース状態は変わらない）

Cancel メソッドが呼び出された場合

直接設定できない状態もあります。たとえば，データセットを dsInactive 状態にするには，Active プロパティを False に設定するか，データセットの Close メソッドを呼び出します。次の 2 つの文は同じ意味です。

CustTable.Active := False;

CustTable.Close;

それ以外の状態（dsCalcFields，dsUpdateNew，dsUpdateOld，dsFilter）はこのアプリケーションでは設定できません。かわりに Delphi が必要に応じて設定します。たとえば，データセットの OnCalcFields イベントが呼び出されたときには，dsCalcFields 状態が設定されます。OnCalcFields イベントが終わると，データセットは元の状態に戻ります。

メモ	データセットが状態を変える場合は，必ずそのデータセットに関連したデータソースコンポーネントの OnStateChange イベントが呼び出されます。データソースコンポーネントと OnStateChange イベントについては，「TDataSource のイベントの使い方」を参照してください。

以降の各節では，状態を設定するタイミングと方法，状態どうしの関係，適用可能な関連情報の説明箇所などについて，それぞれの状態ごとに概要を示します。


Inactivating a dataset
Inactivating a dataset1089006

Section topics 	参照

閉じているデータセットは非アクティブ状態です。閉じられたデータセットのレコードにはアクセスできません。設計時には，データセットの Active プロパティを True に設定するまでデータセットは閉じています。実行時には，アプリケーションが Open メソッドを呼び出すかデータセットの Active プロパティを True に設定するまでデータセットは閉じています。

非アクティブなデータセットを開くと，そのデータセットは自動的に参照状態になります。図に非アクティブ状態，参照状態とそれらを設定するメソッドの関係を示します。

非アクティブ状態と参照状態の関係

データセットを非アクティブにするには，データセットの Close メソッドを呼び出します。データセットの Close メソッドに応答する 2 つのイベントハンドラ BeforeClose と AfterClose を記述できます。たとえば，アプリケーションが Close を呼び出したときにデータセットが dsEdit モードまたは dsInsert モードになっている場合には，保留されている変更を登録するか，取り消すかをデータセットを閉じる前に選択するよう，ユーザーに対して確認メッセージを表示する必要があります。ここで述べたイベントハンドラのコード例を次に示します。

procedure CustTable.VerifyBeforeClose(DataSet: TDataSet)

begin

if (CustTable.State = dsEdit) or (CustTable.State = dsInsert) then

begin

if MessageDlg('Post changes before closing?', mtConfirmation, mbYesNo, 0) = mrYes then

CustTable.Post;

else

CustTable.Cancel;

end;

end;

設計時に，あるプロシージャをデータセットの BeforeClose イベントと関連付ける手順は次のとおりです。

1.	データモジュールまたはフォームのデータセットコンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページをクリックします。

3.	BeforeClose イベントのプロシージャ名を入力するか，ドロップダウンリストからプロシージャ名を選択します。


Browsing a dataset
Browsing a dataset1089007

Section topics 	参照

アプリケーションがデータセットを開くと，データセットは自動的に dsBrowse 状態になります。この参照状態ではデータセットのレコードの表示はできますが，レコードの編集や新規レコードの追加はできません。dsBrowse を主に使うのは，データセットのレコード間をスクロールするときです。レコード間のスクロールの詳細については，「データセットの操作」を参照してください。

dsBrowse からはほかのどのデータセット状態にも設定できます。たとえば，データセットの Insert メソッドまたは Append メソッドを呼び出すと，データセットの状態は dsBrowse から dsInsert に変わります。ただし，ほかの要因や CanModify などのデータセットのプロパティによってはそのように変化しないこともあるので注意してください。SetKey を呼び出してレコードを検索すると，データセットは dsSetKey モードになります。データセットでのレコードの挿入と追加の詳細については，「データの変更」を参照してください。

すべてのデータセットに関連付けられた 2 つのメソッドがデータセットを dsBrowse 状態に戻せます。そのうちの 1 つのCancel は，現在の編集，挿入，検索の各作業を取り消し，データセットを必ず dsBrowse 状態に戻します。もう 1 つの Post はデータベースに変更を書き込もうとします。書き込みに成功すると，やはりデータセットは dsBrowse 状態に戻ります。Post が失敗した場合は現在の状態は変わりません。

図に dsBrowse とアプリケーションで設定できるその他のデータセットモードの関係，およびその各モードを設定する各メソッドと dsBrowse の関係を示します。

参照状態とその他のデータセット状態の関係


Enabling dataset editing
Enabling dataset editing1089008

Section topics 	参照

アプリケーションがレコードを変更できるようにするには，その前にデータセットを dsEdit モードにしなければなりません。データセットの CanModify 読み出し専用プロパティが True であれば，コードで Edit メソッドを使ってデータセットを dsEdit モードにできます。データセットの基になるデータベースが読み書き可能であれば，CanModify は True になります。

アプリケーションのフォーム上では，以下の条件がすべて満たされると，データベース対応コントロールが自動的にデータセットを dsEdit 状態にします。

コントロールの ReadOnly プロパティがデフォルトの False である

コントロールのデータソースの AutoEdit プロパティが True である

データセットの CanModify プロパティが True である

重要	TTable コンポーネント（および RequestLive が False に設定されている場合の TQuery コンポーネント）の場合，ReadOnly プロパティが True なら CanModify は False になり，レコードの編集は防止されます。

メモ	データセットが dsEdit 状態になっていても，アプリケーションのユーザーに適正な SQL アクセス権がない場合には，SQL ベースのデータベースでレコード編集ができない場合もあります。

Cancel，Post，Delete の各メソッドを呼び出して，コードでデータセットを dsEdit 状態から dsBrowse 状態に戻せます。Cancel は，現在の項目または現在のレコードに対する編集内容を破棄します。Post は変更されたレコードをデータセットに書き込もうと試み，成功するとデータセットを dsBrowse 状態に戻します。Post で変更の書き込みができない場合，データセットは dsEdit 状態のままです。Delete は，現在のレコードをデータセットから除去しようと試み，成功すると，データセットを dsBrowse 状態に戻します。Delete が失敗に終わった場合，データセットは dsEdit 状態のままです。

グリッド中の別のレコードに移動するなどの現在のレコードを変える操作や，フォーム上で別のコントロールに移動するなどのコントロールがフォーカスを失うような操作をユーザーが実行した場合，編集が有効になっているデータベース対応コントロールは自動的に Post を呼び出します。

データセットでの項目とレコードの編集の詳細については，「データの変更」を参照してください。


Enabling insertion of new records
Enabling insertion of new records1089009

Section topics 	参照

アプリケーションが新しいレコードを追加するには，その前にデータセットを dsInsert モードにしなければなりません。データセットの CanModify 読み出し専用プロパティが True であれば，コードで Insert メソッドか Append メソッドを使ってデータセットを dsInsert モードにできます。データセットの基になるデータベースが読み書き特権を許可すれば，CanModify は True になります。

アプリケーションのフォーム上では，以下の条件がすべて満たされると，データベース対応のグリッドコントロールとナビゲータコントロールがデータセットを dsInsert 状態にできます。

コントロールの ReadOnly プロパティがデフォルトの False である

コントロールのデータソースの AutoEdit プロパティが True である

データセットの CanModify プロパティが True である

重要	TTable コンポーネントだけは，ReadOnly プロパティが True なら CanModify は False になり，レコードの編集は防止されます。

メモ	データセットが dsInsert 状態になっていても，アプリケーションのユーザーに適正な SQL アクセス権がない場合には，SQL ベースのデータベースでレコードの挿入ができない場合もあります。

Cancel，Post，Delete の各メソッドを呼び出して，コードでデータセットを dsInsert 状態から dsBrowse状態に戻せます。Delete とCancel は新しいレコードを破棄します。Post メソッドは新規レコードをデータセットに書き込もうと試み，成功するとデータセットを dsBrowse 状態に戻します。Post でレコードの書き込みができない場合，データセットは dsInsert 状態のままです。

グリッド中の別のレコードに移動するなどの現在のレコードを変える操作をユーザーが実行した場合，挿入が有効になっているデータベース対応コントロールは自動的に Postを呼び出します。

データセットでのレコードの挿入と追加の詳細については，「データの変更」を参照してください。


Enabling index-based searches and ranges on tables
Enabling index-based searches and ranges on tables1089010

Section topics 	参照

TDataSet の Locate メソッドと Lookup メソッドを使えばすべてのデータセットで検索ができます。しかし，TTable コンポーネントには，GotoKey 系メソッドと FindKey 系メソッドが追加されており，これらのメソッドを使っても，テーブルインデックスに基づいてレコードを検索できます。テーブルコンポーネントでこれらのメソッドを使うには，コンポーネントを dsSetKey モードにしなければなりません。dsSetKey モードは TTable コンポーネントにだけ適用できます。データセットを dsSetKey モードにするには，実行時に SetKey メソッドを使います。検索メソッド GotoKey，GotoNearest，FindKey，FindNearest は検索が終わるとデータセットを dsBrowse 状態に戻します。インデックスを使ったテーブルの検索についての詳細は，「テーブルの操作」を参照してください。

フィルタを使うとデータセットのデータの一部だけを一時的に表示して編集できます。フィルタについては，「フィルタを使って編集する」を参照してください。TTable コンポーネントでは，範囲という使用可能なレコード群にアクセスすることもできます。範囲を作成してテーブルに適用するには，テーブルを dsSetKey モードにしなければなりません。範囲の使い方についての詳細は，「テーブルの操作」を参照してください。


Calculating fields
Calculating fields1089011

Section topics 	参照

アプリケーションがデータセットのイベントハンドラ OnCalcFields を呼び出すと，そのデータセットは必ず dsCalcFields モードになります。このモードでは，イベントハンドラ自身が変更する計算項目を除いて，データセットのレコードに対する変更や追加はできません。目的とする計算項目以外の変更ができないのは，OnCalcFields が，ほかの項目の値を使って計算項目の値を決定するからです。もし，計算項目を処理している間に関係する項目が変更できたとすると，得られる結果は信頼できないものになるでしょう。

イベントハンドラ OnCalcFields が終了すると，データセットは dsBrowse 状態に戻ります。

計算項目と OnCalcFields イベントハンドラの作成については，「OnCalcFields イベント」を参照してください。


Filtering records
Filtering records1089012

Section topics 	参照

アプリケーションがデータセットのイベントハンドラ OnFilterRecord を呼び出すと，そのデータセットは必ず dsFilter モードになります。このモードでは，フィルタ要求が無効になるのを避けるため，フィルタ処理中のデータセットについてはレコードの変更や追加が防止されます。フィルタ処理については，「フィルタを使って編集する」を参照してください。

イベントハンドラ OnFilterRecord が終了すると，データセットは dsBrowse状態に戻ります。


Updating records
Updating records1089013

Section topics 	参照

キャッシュアップデート操作を実行する場合は，データセットは一時的に，dsNewValue，dsOldValue，または dsCurValue のどれかになります。これらの状態は，対応するフィールドコンポーネントのプロパティ（それぞれ，NeValue，OldValue，および CurValue）が，通常 OnUpdateError イベントハンドラ内でアクセスされていることを示します。アプリケーションではこれらの状態を参照/設定することはできません。キャッシュアップデートについては，「キャッシュアップデートの操作」を参照してください。


Navigating datasets
Navigating datasets1089014

Section topics 	参照

アクティブなデータセットにはデータセットの現在の行を指すカーソル，つまりポインタがあります。データセットの現在の行には，編集，挿入，削除のメソッドで操作できる値があります。また，現在の行の項目値は TDBEdit，TDBLabel，TDBMemo などのフォーム上の単一項目のデータベース対応コントロールに表示されます。

カーソルを別の行に移動すれば現在の行を変更できます。表に別のレコードへの移動のためにアプリケーションのコードで使えるメソッドを示します。

メソッド	説明
First	カーソルをデータセットの最初の行に移動する
Last	カーソルをデータセットの最後の行に移動する
Next	カーソルをデータセットの次の行に移動する
Prior	カーソルをデータセットの前の行に移動する
MoveBy	カーソルをデータセット内で指定された行だけ前後に移動する
データベース対応のビジュアルコンポーネント TDBNavigator は，以上のメソッドをボタンとしてカプセル化し，ユーザーが実行時にそのボタンをクリックしてレコード間を移動できるようにしています。ナビゲータコンポーネントについては，「データコントロールの使い方」を参照してください。

これらのメソッドに加え，データセットのレコードを繰り返し処理するときに役立つ情報を提供するものとして，以下の 2 つのプロパティがあります。

プロパティ	説明
BOF （ファイルの開始）	True の場合，カーソルはデータセットの最初の行にある False の場合，カーソルはデータセットの最初の行にはない
EOF （ファイルの終わり）	True の場合，カーソルはデータセットの最後の行にある False の場合，カーソルはデータセットの最後の行にはない


Using the First and Last methods
Using the First and Last methods1089015

Section topics 	参照

First メソッドはカーソルをデータセットの最初の行に移動し，BOF プロパティを True にします。カーソルがすでにデータセットの最初の行にある場合は，First メソッドを指定しても何も起こりません。

たとえば次のコードは，CustTable の最初のレコードに移動するためのコードです。

CustTable.First;

Last メソッドはデータセットの最後の行にカーソルを移動し，EOF プロパティを True に設定します。カーソルがすでにデータセットの最後の行にある場合は，Last メソッドを指定しても何も起こりません。

次のコードは，CustTable の最後のレコードに移動するためのコードです。

CustTable.Last;

メモ	ユーザーに介入されずにデータセットの最初か最後の行に移動するようなプログラムになっているとしても，ユーザーが TDBNavigator コンポーネントを使ってレコード間を移動できるようにする必要があります。ナビゲータコンポーネントには，アクティブで表示もされているときは，ユーザーが押してアクティブなデータセットの最初と最後の行に移動するためのボタンが 2 つあります。これらのボタンの OnClick イベントはデータセットの First メソッドと Last メソッドをそれぞれ呼び出します。ナビゲータコンポーネントについては，「データコントロールの使い方」を参照してください。


Using the Next and Prior methods
Using the Next and Prior methods1089016

Section topics 	参照

Next メソッドは，データセットが空でなければデータセットのカーソルを 1 行先に進め，BOF プロパティを False に設定します。Next メソッドを呼び出したときにカーソルがすでにデータセットの最後の行にある場合は，何も起こりません。

たとえば次のコードは，CustTable の中で次のレコードに移動するためのコードです。

CustTable.Next;

Prior メソッドは，データセットが空でなければデータセットのカーソルを 1 行前に戻し，EOF プロパティを False に設定します。Prior メソッドを呼び出したときにカーソルがすでにデータセットの最初の行にある場合は，何も起こりません。

たとえば次のコードは，CustTable の中で前のレコードに移動するためのコードです。

CustTable.Prior;


Using the MoveBy method
Using the MoveBy method1089017

Section topics 	参照

MoveBy メソッドはデータセットのカーソルを前後に何行移動するかを指定するのに使います。移動は MoveBy が呼び出されたときの現在のレコードを基準にして相対的に実行します。また，MoveBy メソッドはデータセットの BOF プロパティと EOF プロパティを状況に応じて True か False のどちらかに設定します。

この関数には移動するレコード数を指定する整数のパラメータがあります。正の整数は先へ進む移動を示し，負の整数は後へ戻る移動を示します。

MoveBy メソッドは移動した行数を返します。データセットの最初や最後を超えるような移動を試みた場合，MoveBy が返す行数は移動するよう指定した行数と異なります。これは MoveBy がデータセットの最初や最後のレコードに到達するとそこで止まるからです。

次のコードは，CustTable で 2 レコード前に戻るためのコードです。

CustTable.MoveBy(-2);

メモ	アプリケーションで MoveBy メソッドを使い，マルチユーザーデータベース環境にいる場合，データセットは流動的であることを忘れないでください。ある時点で 5 レコード先にあったレコードが，わずかの間に 4 レコード先になったり，6 レコードあるいはそれ以上になったりします。これは複数のユーザーが同時にデータベースにアクセスして，そのデータを変更することがあるためです。


Using the EOF and BOF properties
Using the EOF and BOF properties1089018

Section topics 	参照

読み出し専用の実行時のプロパティとして，EOF（ファイルの終わり）と BOF（ファイルの始まり）という 2 つのプロパティがあります。この 2 つのプロパティはデータセット内の移動，特にデータセット内のすべてのレコードを繰り返し処理するときなどの制御に便利です。

EOF1089019

EOF プロパティが True のとき，カーソルはデータセットの最後の行にあります。EOF が True に設定されるのは，アプリケーションが以下の動作をしたときです。

空のデータセットを開いた

データセットの Last メソッドを呼び出した

データセットの Next メソッドを呼び出したが，データセットの最後の行にカーソルがあったために Next メソッドが失敗した

空の範囲またはデータセットで SetRange を呼び出した

以上の場合以外では，EOFプロパティは必ず False になります。

EOF プロパティは，データセットのすべてのレコードの繰り返し処理を制御するためにループ条件でよくテストします。レコードの入ったデータセットを開いたり First メソッドを呼び出すと，EOF は False になります。1 レコードずつデータセット全体の繰り返し処理をするには，EOF が True になるとループが終了するようにループを作成します。ループの中でデータセットのレコードごとに Nextメソッドを呼び出します。カーソルがすでに最後のレコードにある場合は，Next を呼び出すまで EOF は False のままです。

次のコードは，CustTable というデータセットのレコード処理ループのコード記述方法の 1 つを示しています。

CustTable.DisableControls;

try

CustTable.First;	{第 1 レコードへ移動し，EOF を False にする}

while not CustTable.EOF do	{EOF が True になるまで繰り返す}

begin

{ 各レコードを処理する }

...

CustTable.Next;	{成功した場合には EOF は False になる。
最後のレコードに対し Next を呼ぶと失敗し
EOF は True になる}

end;

finally

CustTable.EnableControls;

end;

参考	上記の例では，データセットに結び付けられたデータベース対応ビジュアルコントロールを使用可能にしたり，使用不可にしたりする方法も示してします。データセットの繰り返し処理中にビジュアルコントロールを使用不可にすると，現在のレコードが変更されてもそのたびにコントロールの内容を更新する必要がないため，処理速度が上がります。繰り返し処理が完了したら，再びコントロールを使用可能にして，新しい現在行の値でコントロールを更新する必要があります。ビジュアルコントロールは try...finally 文の finally 節で使用可能にすることに注意してください。この処理によって，たとえ例外が発生してループ処理が未完了で終わってもコントロールが使用不可のまま終わることはないからです。

BOF1089020

BOF プロパティが True のとき，カーソルはデータセットの最初の行にあります。BOF が True に設定されるのは，アプリケーションが以下の動作をしたときです。

空のデータセットを開いた

データセットの First メソッドを呼び出した

データセットの Prior メソッドを呼び出したが，データセットの最初のレコードにカーソルがあったために Prior メソッドが失敗した

空の範囲またはデータセットで SetRange を呼び出した

以上の場合以外では，BOFプロパティは必ず False になります。

EOF と同様に BOF もループ条件に入ってデータセットのレコードの繰り返し処理を制御できます。次のコードは，CustTable というデータセットのレコード処理ループのコード記述方法の 1 つを示しています。

CustTable.DisableControls;	{画面描画を止めることで処理速度を上げ，
ちらつきをさける}

try

while not CustTable.BOF do {BOF が True になるまで繰り返す}

begin

{ 各レコードを処理する }

...

CustTable.Prior;	{成功した場合には BOF は False になる。
最初のレコードに対し Priorを呼ぶと失敗し，
BOF は Trueとなる}

end;

finally

CustTable.EnableControls;	{新しい現在行を表示する}

end;


Marking and returning to records
Marking and returning to records1089021

Section topics 	参照

データセット内であるレコードから別のレコードに移動したり，レコード数を指定してレコード間を移動する以外に，データセットの特定の位置にマークを付けて必要なときにすぐにその位置に戻れるようにしておくと便利です。TDataSet とその下位オブジェクトではブックマーク機能を実装できます。この機能を使うと，レコードにタグを付け，後でそのレコードに戻ることができます。ブックマーク機能は 1 つの Bookmark プロパティと，5 つのブックマークメソッドで構成されます。

Bookmark プロパティは，アプリケーション内のいくつものブックマークのうちどれが現在のものかを示します。Bookmark は現在のブックマークを特定する文字列です。別のブックマークを追加するたびに，追加したものが現在のブックマークになります。

TDataSet は仮のブックマークメソッドを用意しています。TDataSet から継承されたオブジェクトからこれらのTDataSetで定義されているメソッドを呼んだ場合には仮の値が返されます。TBDEDataSet などの TDataSetから継承されたオブジェクトでは，それぞれのデータセットにおける以下の表の意味を持つ，適切な動作を行うように再実装されます。

BookmarkValid	指定したブックマークが使用中かどうか確認する

CompareBookmarks	2 つのブックマークが同じかどうかテストする

GetBookmark	データセットの現在位置にブックマークを付ける

GotoBookmark	GetBookmark で以前に作ったブックマークに戻る

FreeBookmark	GetBookmark で以前に付けたブックマークを解除する

ブックマークを作るには，アプリケーションで TBookmark 型の変数を宣言してから，GetBookmark を呼び出してその変数に記憶域を割り当て，さらにその変数の値にデータセットの特定の位置を設定しなければなりません。

GotoBookmark を呼び出して特定のレコードに移動する前に，BookmarkValid を呼び出して，ブックマークが正しくレコードを指しているかどうか確認できます。指定されたブックマークがレコードを指していれば BookmarkValid は True を返します。TDataSet では，仮のメソッドなので BookmarkValid は必ず False を返してブックマークが無効なことを示します。TDataSet の下位オブジェクトはこのメソッドを再実装して，有効な値を返します。

移動先のブックマークが別の（または現在の）ブックマークと異なっているかどうか確認するため，CompareBookmarks を呼び出すこともできます。TDataSet.CompareBookmark は必ず 0 を返してブックマークが同じでないことを示します。TDataSet の下位オブジェクトはこのメソッドを再実装して，有効な値を返します。

GotoBookmark にブックマークを渡すと，ブックマークで指定した位置にデータセットのカーソルが移動します。TDataSet.GotoBookmark は内部の抽象メソッドを呼び出します。これを呼び出すと実行時エラーになります。TDataSet の下位オブジェクトはこのメソッドを再実装して，有効な値を返します。

FreeBookmark は，不要になったブックマークに割り当てられているメモリを解除します。FreeBookmark は，既存のブックマークを再利用する前にも呼び出す必要があります。

次のコードはブックマークの使い方の一例を示しています。

procedure DoSomething (const Tbl: TTable)

var

Bookmark: TBookmark;

begin

Bookmark := Tbl.GetBookmark; {メモリを割り当て，値を代入する}

Tbl.DisableControls; {コントロールのレコード表示をオフにする}

try

Tbl.First; {テーブルの第 1 レコードに移動する}

while not Tbl.EOF do {テーブルの各レコードを繰り返し処理する}

begin

{ 処理を実行する }

...

Tbl.Next;

end;

finally

Tbl.GotoBookmark(Bookmark);

Tbl.EnableControls; {必要に応じてデータコントロールのレコード表示をオンにする}

Tbl.FreeBookmark(Bookmark); {ブックマークのメモリ割り当てを解除する}

end;

end;

レコードの繰り返し処理に入る前に，途中経過を表示させないようにして速度を上げるためにコントロールは使用不可にされます。レコードの繰り返し処理中にエラーが発生すると，ループ処理が未完了であったとしても，finally 節で，コントロールは常に使用可能にされ，ブックマークは常に解除されます。


Searching datasets
Searching datasets1089022

Section topics 	参照

特定のレコードを見つけるためのデータセット検索には，一般的な検索メソッドとして Locate と Lookup の 2 つが使えます。この 2 つのメソッドは任意のデータセットのどの列でも検索ができます。

Using Locate1089023

Locate メソッドは指定された検索条件に一致する最初の行にカーソルを移動します。もっとも簡単な形式としては，検索対象の列名，比較の基準になる項目値を Locate に渡し，さらに大文字小文字の区別なしの検索なのか，部分キー照合を使えるかなどを指定するオプションフラグを渡します。たとえば次のコードは，Company の列の値が「Professional Divers，Ltd.」であるような CustTable の最初の行にカーソルを移動します。

var

LocateSuccess: Boolean;

SearchOptions: TLocateOptions;

begin

SearchOptions := [loPartialKey];

LocateSuccess := CustTable.Locate('Company', 'Professional Divers, Ltd.',
SearchOptions);

end;

Locate メソッドでは一致すると，一致した最初のレコードが現在のレコードになります。一致するレコードが見つかった場合，Locate は True を返します。見つからなかった場合，Locate は False を返します。検索に失敗した場合，現在のレコードは変わりません。

Locate は，複数の列で複数の値を検索する場合に最も力を発揮します。検索する値はバリアントであり，ここでは検索条件として，異なるデータ型を指定できます。検索文字列に複数の列を指定するには，その文字列の各項目をセミコロンで区切ります。

検索値はバリアントであるため，複数の値を渡す場合は，たとえば Lookup メソッドからの戻り値などのバリアント配列型を引数として指定するか，あるいは VarArrayOf 関数を使ってその場でバリアント配列を作成しなければなりません。次のコードは，複数の検索値と部分キー照合を使って複数の列で検索するコードの例です。

with CustTable do

Locate('Company;Contact;Phone', VarArrayOf(['Sight Diver','P']), loPartialKey);

Locate は可能な限り速い方法を使って一致するレコードの位置を突き止めます。検索する列がインデックス付きで，そのインデックスが指定の検索オプションと互換性があれば，Locate はそのインデックスを使います。フィルタの詳細については，「フィルタを使って編集する」を参照してください。

Using Lookup1089024

Lookup メソッドは指定された検索条件に一致する最初の行を探します。一致する行が見つかると，そのデータセットに関連した計算項目と参照項目が必ず再計算され，一致した行から 1 つまたは複数の項目が返されます。Lookup はカーソルを一致した行には移動せず，そこから値を返すだけです。

もっとも簡単な形式としては，検索対象の列名，比較の基準になる項目値，返すべき 1 つまたは複数の項目を Lookup に渡します。たとえば次のコードは，Company 列の値が「Professional Divers，Ltd.」であるような CustTable の最初の行を検索し，会社名，担当者，会社の電話番号を返します。

var

LookupResults: Variant;

begin

with CustTable do

LookupResults := Lookup('Company', 'Professional Divers, Ltd.', 'Company;
Contact; Phone');

end;

Lookup メソッドは，検索の結果最初に一致したレコードから，指定された項目の値を返します。戻り値はバリアントです。複数の値を返すように指定すると，Lookup はバリアント配列を返します。一致するレコードがない場合，Lookup はヌルのバリアントを返します。バリアント配列については，『Object Pascal 言語リファレンス』を参照してください。

Lookup メソッドは，複数の列で複数の値を検索する場合に最も力を発揮します。複数の列や結果項目を持つ文字列を指定するには，その文字列の各項目をセミコロンで区切ります。

検索値はバリアントであるため，複数の値を渡す場合は，たとえば Lookup メソッドからの戻り値などのバリアント配列型を引数として指定するか，VarArrayOf 関数を使ってその場でバリアント配列を作成しなければなりません。次のコードは，複数の列で Lookup の検索をするコードの例です。

var

LookupResults: Variant;

begin

with CustTable do

LookupResults := Lookup('Company; City', VarArrayOf(['Sight Diver', 'Christiansted']),
'Company; Addr1; Addr2; State; Zip');

end;

Lookup メソッドは可能な限り速い方法を使って一致するレコードの位置を突き止めます。検索する列がインデックス付きであれば，Lookup はそのインデックスを使います。フィルタについての詳細は「フィルタを使って編集する」を参照してください。


Displaying and editing a subset of data using filters
Displaying and editing a subset of data using filters1089025

Section topics 	参照

ほとんどの場合，データセット内でアプリケーションの操作対象になるレコードはほんの一部分だけです。たとえば，顧客データベースの中のカリフォルニアを拠点とする会社のレコードだけを取り出したり表示したい場合や，特定の項目値セットを持つレコードを見つけたい場合などです。このような場合，フィルタを使うと，アプリケーションがデータセット内の特定のレコードだけにアクセスするようになります。

フィルタは条件を指定し，その条件に一致するレコードだけが表示されます。フィルタ条件は，データセットの Filter プロパティで指定することも，OnFilterRecord イベントハンドラに記述することもできます。フィルタ条件は，指定した数のデータセット項目にインデックスが付いているかどうかにかかわらず，これらの項目の値に基づいて設定されます。たとえば，カリフォルニアを拠点とする会社のレコードだけを表示するには，State 項目の値が「CA」であるレコードを探す単純なフィルタを使います。

メモ	フィルタはデータセットで取り出したすべてのレコードに対して適用されます。大量のデータをフィルタにかける場合は，問い合わせを使ってレコードの取り出しを制限するか，インデックス付きテーブル上で範囲指定をする方がフィルタを使うよりも効果的なことがあります。


Enabling and disabling filtering
Enabling and disabling filtering1089026

Section topics 	参照

データセットでフィルタを設定する手順は次のとおりです。

1.	フィルタを作成します。

2.	必要に応じて，文字列に基づくフィルタテストのオプションを設定します。

3.	Filtered プロパティを True に設定します。

フィルタを設定すると，フィルタ条件に一致するレコードだけをアプリケーションで使えます。フィルタは一時的な条件にすぎません。フィルタを解除するには，Filtered プロパティを False に設定します。


Creating filters
Creating filters1089027

Section topics 	参照

データセットのフィルタを作成するには，以下の 2 通りの方法があります。

Filter プロパティで単純なフィルタ条件を指定する。Filter プロパティは実行時にフィルタを作成して適用する場合に特に便利である

OnFilterRecord イベントハンドラを記述する。単純なフィルタ条件も複雑なフィルタ条件も作成できる。OnFilterRecord では設計時にフィルタ条件を指定する。Filter プロパティでは 1 つの文字列でフィルタ論理を指定しなければならないが，OnFilterRecord イベントハンドラの場合は論理を分岐またはループさせて複雑な多重フィルタ条件を作成できる

Filter プロパティを使ってフィルタを作成する主な利点は，アプリケーションが動的に，たとえばユーザーの入力に応じて，フィルタの作成，変更，適用ができることです。欠点は，フィルタ条件を 1 つのテキスト文字列で表さなければならないことです。また，分岐やループの構造を利用できず，データセットにまだ存在していない値との比較やテストもできません。

OnFilterRecord イベントの利点は，複雑で調整可能なフィルタを作成でき，分岐やループの構造を使う複数行にわたるコードを使えることです。データセットの値をそのデータセットにない値（編集ボックス内のテキストなど）と比較してテストすることもできます。OnFilterRecord イベントを使う場合の欠点は，フィルタを設計時に設定するのでユーザーの入力に応じて変更できないことです。ただし，複数のフィルタハンドラを作成して，一般的なアプリケーション条件に応じてフィルタハンドラを切り替えることができます。

以降の各節では，Filter プロパティと OnFilterRecord イベントハンドラを使ってフィルタを作成する方法について説明します。


Setting the Filter property
Setting the Filter property1089028

Section topics 	参照

Filter プロパティを使ってフィルタを作成するには，このプロパティの値として，フィルタ条件を示す文字列を設定します。文字列ではフィルタのテスト条件を指定します。たとえば次の文は，データセットの State 項目をテストして，カリフォルニア州を表す値が入っているかどうか調べるフィルタを作成します。

Dataset1.Filter := 'State' = 'CA';

コントロールに入力したテキストに基づいて Filter の値を指定することもできます。たとえば次の文は，編集ボックスのテキストを Filter に代入します。

Dataset1.Filter := Edit1.Text;

ハードコードされたテキストと，コントロールにユーザーが入力したデータの両方に基づいて文字列を作成することもできます。

Dataset1.Filter := 'State' + ' ' + Edit1.Text;

Filter の値を指定した後にフィルタをデータセットに適用するには，Filtered プロパティ を True に設定します。

次の比較演算子と論理演算子を使うと，項目値どうしの比較のほか，項目値をリテラルまたは定数と比較できます。

演算子	意味
<	より小さい
>	より大きい
>=	以上
<=	以下
=	等しい
<>	等しくない
AND	2 つの文がどちらも True か調べる
NOT	次の文が True でないか調べる
OR	2 つの文のどちらか一方または両方が True か調べる
これらの演算子を組み合わせて使うと，高度なフィルタを作成できます。たとえば次の文は，2 つのテスト条件を満足していることを確認してから，レコードの表示を認めます。

(Custno > 1400) AND (Custno < 1500);

メモ	フィルタが設定されているときにユーザーがレコードに編集を加えると，そのレコードがフィルタのテスト条件に合わなくなることもあります。そのレコードを次にデータセットから取り出したときには，それが「消えて」いるように見えるかもしれません。その場合，そのフィルタ条件に一致した次のレコードが現在のレコードになります。


Writing an OnFilterRecord event handler
Writing an OnFilterRecord event handler1089029

Section topics 	参照

データセットのフィルタは，レコードを取り出すたびにデータセットが生成した OnFilterRecord イベントに応答するイベントハンドラです。フィルタハンドラの中心的な機能は，あるレコードをアプリケーションで表示すべきかどうか判断することです。

レコードがフィルタ条件に一致しているかどうかを示すには，フィルタハンドラが Accept パラメータを True（レコードの採用）または False（レコードの除外）に設定しなければなりません。たとえば次のようなフィルタは，State 項目が「CA」に設定されているレコードだけを表示します。

procedure TForm1.Table1FilterRecord(DataSet: TDataSet; var Accept: Boolean);

begin

Accept := DataSet['State'] = 'CA';

end;

フィルタを設定すると，レコードを取り出すたびに OnFilterRecord イベントが発生します。イベントハンドラはそのレコードを調べて，フィルタ条件に一致するレコードだけを表示します。OnFilterRecord イベントはデータセット内のすべてのレコードに対して発生するので，アプリケーションの処理効率に影響しないように，このイベントハンドラはできるだけ簡潔に記述しておかなければなりません。

Switching filter event handlers at run time1089030

フィルタのイベントハンドラは必要なだけ記述し，実行時に切り替えることができます。実行時に別のフィルタのイベントハンドラに切り替えるには，新しいイベントハンドラをデータセットの OnFilterRecord プロパティに代入します。

たとえば次の文は，NewYorkFilter という OnFilterRecord イベントハンドラに切り替えます。

DataSet1.OnFilterRecord := NewYorkFilter;


Setting filter options
Setting filter options1089031

Section topics 	参照

FilterOptions プロパティを使うと，フィルタで文字列ベースの項目を比較するときに部分的な比較に基づいてレコードを受け付けるかどうか，また，大文字と小文字を区別して文字列を比較するかどうかを指定できます。FilterOptions は集合プロパティです。空集合にすることも（デフォルト），以下の値のどちらか一方または両方を含むこともできます。

値	意味
foCaseInsensitive	文字列を比較するときに大文字と小文字を区別しない
foNoPartialCompare	部分的一致は受け付けない（たとえば，* で終わる文字の比較結果は不一致）
たとえば次の文は，State 項目で値を比較するときに大文字と小文字を区別しないフィルタを設定します。

FilterOptions := [foCaseInsensitive];

Filter := 'State' = 'CA';


Navigate records in a filtered dataset
Navigate records in a filtered dataset1089032

Section topics 	参照

フィルタが設定されたデータセット内のレコード間を移動するには，以下の 4 つのデータセットメソッドが使えます。表にこれらのメソッドとその用途を示します。

メソッド	用途
FindFirst	データセット内で現在のフィルタ条件に一致する最初のレコードに移動する。最初に一致するレコードの検索は，フィルタが設定されていないデータセットの最初のレコードから始まる
FindLast	データセット内で現在のフィルタ条件に一致する最後のレコードに移動する
FindNext	フィルタが設定されたデータセットの現在のレコードから次のレコードに移動する
FindPrior	フィルタが設定されたデータセットの現在のレコードから 1 つ前のレコードに移動する
たとえば次の文は，データセットで最初にフィルタ処理されたレコードを探します。

DataSet1.FindFirst;

アプリケーションで Filter プロパティを設定するか，OnFilterRecord イベントハンドラを作成すると，そのデータセットでフィルタが現在設定されているかどうかに関係なく，これらのメソッドは指定されたレコードにカーソルを移動します。フィルタが設定されていないときにこのメソッドを呼び出すと，次のような処理が行われます。

1.	一時的にフィルタが設定される

2.	一致するレコードが見つかればそのレコードにカーソルが移動する

3.	フィルタが解除される

メモ	フィルタが解除されているときに Filter プロパティの設定も OnFilterRecord イベントハンドラの作成もしなければ，これらのメソッドは何もしません。

移動用フィルタメソッドはどれも，一致するレコードが見つかるとそのレコードにカーソルを移動し，そのレコードを現在のレコードにしてから True を返します。一致するレコードが見つからないと，カーソルの位置はそのままで変わらず，これらのメソッドは False を返します。たとえば，データセットで一致する最後のレコードにカーソルがすでにあるときに FindNext を呼び出すと，このメソッドは False を返し，現在のレコードは変化しません。


Modifying data
Modifying data1089033

Section topics 	参照

データの挿入，更新，削除には以下のデータセットメソッドを使います。

メソッド	説明
Edit	データセットが dsEdit や dsInsert の状態でない場合は，dsEdit 状態にする
Append	保留状態のデータを登録し，現在のレコードをデータセットの最後に移動し，データセットを dsInsert 状態にする
Insert	保留状態のデータを登録し，データセットを dsInsert 状態にする
Post	新規のレコードや変更されたレコードをデータベースに登録しようと試みる。正常終了の場合，データセットは dsBrowse 状態になる。異常終了の場合，データセットの状態は変わらない
Cancel	現在の動作を取り消して，データセットを dsBrowse 状態にする
Delete	現在のレコードを削除して，データセットを dsBrowse 状態にする


Editing records
Editing records1089034

Section topics 	参照

アプリケーションでレコードを変更するには，その前にデータセットを dsEdit モードにしなければなりません。データセットの CanModify 読み出し専用プロパティが True であれば，コードで Edit メソッドを使ってデータセットを dsEdit モードにできます。データセットの基になるテーブルが読み書き特権を許可すれば，CanModify は True になります。

アプリケーションのフォーム上では，以下の条件がすべて満たされると，データベース対応コントロールの一部がデータセットを自動的に dsEdit 状態にできます。

コントロールの ReadOnly プロパティがデフォルトの False である

コントロールのデータソースの AutoEdit プロパティが True である

データセットの CanModify プロパティが True である

重要	TTable コンポーネント（および，RequestLive プロパティが False 設定されている場合の TQuery コンポーネント）の場合，ReadOnly プロパティが True なら CanModify プロパティは False になり，レコードの編集は防止されます。

メモ	データセットが dsEdit 状態になっていても，アプリケーションユーザーに適切な SQL アクセス権がない場合には，SQL ベースのデータベースでレコードの編集ができないこともあります。

いったんデータセットが dsEdit モードになると，ユーザーはフォーム上のデータベース対応コントロールに表示される現在のレコードの項目値を変更できます。グリッド中の別レコードに移動するなどの現在のレコードを変更する操作をユーザーが実行した場合，編集が有効になっているデータベース対応コントロールは自動的に Post を呼び出します。

フォーム上にナビゲータコンポーネントを提供した場合，ユーザーはそのナビゲータの編集の取り消しボタンをクリックして編集を取り消せます。編集を取り消すとデータセットは dsBrowse 状態に戻ります。

コードで適切なメソッドを呼び出すことによって，編集を書き込むか取り消すかのどちらかを選ばなければなりません。Post の呼び出しでは変更を書き込みます。Cancel の呼び出しでは取り消します。コードでは Edit と Post が一緒に使われることがよくあります。次に例を示します。

with CustTable do

begin

Edit;

FieldValues['CustNo'] := 1234;

Post;

end;

begin...end 文の中で，コードの最初の行はデータセットを dsEdit モードにします。次の行は，現在のレコードの CusNo 項目に「1234」という数字を代入します。最後の行は，変更されたレコードをデータベースに書き込んで登録します。

メモ	データセットの CachedUpdates プロパティが True であれば，登録された変更は一時バッファに書き込まれます。キャッシュに格納された編集内容をデータベースに書き込むには，データセットの ApplyUpdates メソッドを呼び出します。キャッシュアップデートの詳細については，を参照してください。


Adding new records
Adding new records1089035

Section topics 	参照

アプリケーションが新規レコードを追加するには，その前にデータセットが dsInsert モードになっていなければなりません。データセットの CanModify 読み書き専用プロパティが True であれば，コードの中で Insert メソッドや Append メソッドを使ってデータセットを dsInsert モードにできます。データセットの基になるデータベースが読み書き特権を許可すれば，CanModify は True になります。

アプリケーションのフォーム上では，以下の条件が両方満たされると，データベース対応のグリッドコントロールとナビゲータコントロールがデータセットを dsInsert 状態にできます。

コントロールの ReadOnly プロパティがデフォルトの False である

データセットの CanModify プロパティが True である

いったんデータセットが dsInsert モードになると，ユーザーまたはアプリケーションは新規レコードの項目に値を入力できます。グリッドコントロールとナビゲータコントロールを除いて，ユーザーには Insert と Append は同じに見えます。Insert メソッドを呼び出すと，現在のレコードだった場所の上のグリッドに空行が表示されます。Append メソッドを呼び出すと，グリッドはデータセットの最後のレコードにスクロールし，グリッドの最後に空行が表示されます。そして，そのデータセットに関連したナビゲータコンポーネントでは次のレコードボタンと最後のレコードボタンが淡色表示になります。

グリッド中の別のレコードに移動するなどの現在のレコードを変更する操作をユーザーが実行した場合，挿入が有効になっているデータベース対応コントロールは自動的に Post を呼び出します。変更する操作をしなかった場合は，コードで Post を呼び出さなければなりません。

Post メソッドは新規レコードをデータベースに書き込みます。あるいは，キャッシュアップデートが使用可能であれば，Post はレコードをバッファに書き込みます。キャッシュに格納された挿入および追加の内容をデータベースに書き込むには，データセットの ApplyUpdates メソッドを呼び出します。キャッシュアップデートについては，「キャッシュアップデートの操作」を参照してください。

Inserting records1089036

Insert メソッドは現在のレコードの前に空のレコードを新しく開き，ユーザーまたはアプリケーションのコードが項目値を入力できるよう，空のレコードを現在のレコードにします。

アプリケーションが Post メソッドを呼び出した場合（キャッシュアップデートが使用可能であれば ApplyUpdates メソッドを呼び出した場合），挿入されたレコードは以下の 3 通りの方法のいずれかでデータベースに書き込まれます。

インデックス付きの Paradox テーブルと dBASE テーブルの場合，レコードはデータセットのそのインデックスに基づいた場所に挿入される

インデックスの付いていないテーブルの場合，レコードはデータセットの現在の場所に追加される

SQL データベースの場合，物理的な挿入場所はシステムによって異なる。テーブルがインデックス付きであれば，新規レコード情報とともにインデックスも更新される

Appending records1089037

Append メソッドはデータセットの最後に空のレコードを新しく開き，ユーザーまたはアプリケーションのコードが項目値を入力できるよう，空のレコードを現在のレコードにします。

アプリケーションが Post メソッドを呼び出した場合（キャッシュアップデートが使用可能であれば ApplyUpdates メソッドを呼び出した場合），追加されたレコードは以下の 3 通りの方法のいずれかでデータベースに書き込まれます。

インデックス付きの Paradox テーブルと dBASE テーブルの場合，レコードはデータセットのそのインデックスに基づいた場所に挿入される

インデックスの付いていないテーブルの場合，レコードはデータセットの最後に追加される

SQL データベースの場合，物理的な追加場所はシステムによって異なる。テーブルがインデックス付きであれば，新規レコード情報と一緒にインデックスも更新される


Deleting records
Deleting records1089038

Section topics 	参照

アプリケーションがレコードを削除するには，その前にデータセットはアクティブになっていなければなりません。Delete は現在のレコードをデータセットから削除し，データセットを dsBrowse モードにします。削除されたレコードの後にあるレコードが現在のレコードになります。データセットのキャッシュアップデートが使用可能であれば，削除されたレコードは，ApplyUpdates メソッドを呼び出すまで一時キャッシュバッファから取り除かれるだけです。

データセットに関連付けられたナビゲータコンポーネントがある場合，ユーザーはそのナビゲータのレコード削除ボタンをクリックして現在のレコードを削除できます。コードで現在のレコードを削除するには，明示的に Delete を呼び出さなければなりません。


Posting data to the database
Posting data to the database1089039

Section topics 	参照

Post メソッドは，Delphi のアプリケーションがデータベーステーブルとやり取りするうえで中心的な役割を果たします。Post は現在のレコードに加えられた変更をデータベースに書き込みますが，Post の動作はデータセットの状態によって異なります。

データセットが dsEdit 状態であれば，Post は変更されたレコードをデータベースに書き込む。キャッシュアップデートが使用可能であれば，書き込み先はバッファである

データセットが dsInsert 状態であれば，Post は新規レコードをデータベースに書き込む。キャッシュアップデートが使用可能であれば，書き込み先はバッファである

データセットが dsSetKey 状態であれば，Post はデータセットを dsBrowse 状態に戻す

登録は明示的に実行することも，別の手続きの一部として暗黙的に実行することもできます。アプリケーションが現在のレコードから出ると，Post メソッドが暗黙的に呼び出されます。テーブルが dsEdit や dsInsert モードになっている場合は，First，Next，Prior，Last の各メソッドを呼び出すと Post が実行されます。Append メソッドと Insert メソッドを呼び出したときも，保留データが暗黙的に登録されます。

メモ	Closeメソッドを呼び出しても Post メソッドは暗黙的に呼び出されません。保留状態の編集内容を登録するには，BeforeClose イベントを明示的に使ってください。


Canceling changes
Canceling changes1089040

Section topics 	参照

アプリケーションが直接または間接に Post メソッドを呼び出していなければ，現在のレコードに加えられた変更はいつでも取り消せます。たとえば，データセットが dsEdit モードになっていてユーザーが 1 つまたは複数の項目のデータを変更したとします。このときアプリケーションはデータセットの Cancel メソッドを呼び出すことでレコードを元の値に戻せます。Cancel を呼び出すとデータセットは必ず dsBrowse 状態に戻ります。

ユーザーが編集，挿入，追加の各操作を取り消せるようにするには，フォーム上でデータセットに関連したナビゲータコンポーネントに編集の取り消しボタンを組み入れます。あるいは，編集の取り消しボタンをコードで記述することもできます。


Modifying entire records
Modifying entire records1089041

Section topics 	参照

フォーム上の，グリッドとナビゲータを除く残りのデータベース対応コントロールはレコード中の 1 つの項目にアクセスできます。

ただし，データセットの基になるデータベーステーブルの構造が安定していて変わらないならば，レコード構造全体を処理する以下のメソッドをプログラムから使えます。表にレコードの個々の項目ではなくレコード単位で処理するメソッドを示します。

メソッド	説明
AppendRecord([値の配列])	指定された列値を持つレコードをテーブルの最後に追加する。Append に似ている。暗黙的に Post を呼び出す
InsertRecord([値の配列])	テーブルの現在のカーソル位置の直前に，指定された値をレコードとして挿入する。Insert と似ている。暗黙的に Post を呼び出す
SetFields([値の配列])	対応する項目の値を設定する。TFields に値を代入することに似ている。アプリケーションは明示的に Post を呼び出さなければならない
以上のメソッドは値がカンマで区切られた配列を引数にします。各値はそれぞれ基になるデータセットの列に相当します。値に指定できるのはリテラル，変数，ヌル，nil です。引数の値の数がデータセットの列数より少ない場合，残りの値はヌルとみなされます。

インデックスの付いていないデータセットの場合，AppendRecord メソッドはデータセットの最後にレコードを追加し，InsertRecord メソッドは現在のカーソル位置の直後にレコードを挿入します。インデックス付きのテーブルでは，どちらのメソッドも，インデックスに基づいてテーブルの正しい指定位置にレコードを追加し，カーソルをレコード位置に移動します。

SetFields メソッドはパラメータ配列で指定された値をデータセットの項目に代入します。SetFields を使うには，アプリケーションが最初に Edit を呼び出してデータセットを dsEdit モードにしなければなりません。変更内容を現在のレコードに適用するには Post を実行しなければなりません。

既存のレコードのすべての項目ではなく，一部の項目を変更するために SetFields メソッドを使う場合は，変更したくない項目について nil 値を渡すことができます。指定した値の数がレコードのすべての項目数より少ない場合，SetFields は Null 値を足りない分に代入します。Null 値は入っている項目値をすべて上書きします。

たとえば，データベースに Name，Capital，Continent，Area，Population という列を持つ COUNTRY というテーブルがあるとします。CountryTable という TTable コンポーネントが COUNTRY テーブルにリンクされていれば，次の文によってレコードが COUNTRY テーブルに挿入されます。

CountryTable.InsertRecord(['Japan', 'Tokyo', 'Asia']);

この文では Area と Population の値を指定していないため，その 2 つの項目にはヌルが挿入されます。テーブルは Name にインデックスが付いているので，次の文は「Japan」をアルファベット順に照合した結果に基づいてレコードを挿入します。

レコードを更新するには，例として次のようなコードを使えます。

To update the record, an application could use the following code:

with CountryTable do

begin

if Locate('Name', 'Japan', loCaseInsensitive) then;

begin

Edit;

SetFields(nil, nil, nil, 344567, 164700000);

Post;

end;

end;

このコードは Area と Population の項目に値を代入し，データベースに登録します。3 つの nil 値は最初の 3 列の現在の内容を保持するためのプレースホルダとして機能します。


Using dataset events
Using dataset events1089042

Section topics 	参照

データセットには，検証の実行，合計の計算などの作業をアプリケーションで実行できるようにするイベントが数多くあります。表にデータセットのイベントを示します。

イベント	説明
BeforeOpen， AfterOpen	データセットを開く前後に呼び出される
BeforeClose， AfterClose	データセットを閉じる前後に呼び出される
BeforeInsert， AfterInsert	データセットが挿入状態になる前後に呼び出される
BeforeEdit， AfterEdit	データセットが編集状態になる前後に呼び出される
BeforePost， AfterPost	テーブルへの変更を登録する前後に呼び出される
BeforeCancel， AfterCancel	以前の状態を取り消す前後に呼び出される
BeforeDelete， AfterDelete	レコードを削除する前後に呼び出される
OnNewRecord	新しいレコードを作成すると呼び出される。デフォルト値の設定に使う
OnCalcFields	計算項目を計算すると呼び出される
TDataSet コンポーネントのイベントについては，オンラインヘルプを参照してください。


Aborting a method
Aborting a method1089043

Section topics 	参照

Open や Insert のようなメソッドを中止するには，BeforeOpen，BeforeInsert などの Before メソッドの 1 つを使って Abort 手続きを呼び出します。Abort は，Open，Insert，Delete などのほかのメソッドが実行されないようにします。通常 Abort は，BeforeOpen，BeforeInsert，BeforeDelete などのイベントハンドラの中で呼び出されます。たとえば次のコードは，ユーザーに対して削除の確認を求め，認められなければ Delete の呼び出しを中止します。

procedure TForm1.TableBeforeDelete (Dataset: TDataset);

begin

if MessageDlg('Delete This Record?', mtConfirmation, mbYesNoCancel, 0) <> mrYes then

Abort;

end;


Using OnCalcFields
Using OnCalcFields1089044

Section topics 	参照

OnCalcFields イベントは，計算項目の値を設定するのに使います。AutoCalcFields プロパティは OnCalcFields を呼び出すタイミングを決めます。AutoCalcFields が True の場合，OnCalcFields は以下のタイミングで呼び出されます。

データセットを開いたとき

フォーカスがあるビジュアルコンポーネントから別のビジュアルコンポーネントへ移動したり，データベース対応グリッドコントロールのある列から別の列へ移動したとき

レコードをデータベースから取り出したとき

AutoCalcFields が True のときには，計算項目以外の項目の値が変化すると，OnCalcFields が必ず呼び出されます。

注意	OnCalcFields イベントは頻繁に呼び出されるため，コードを短くする必要があります。また，AutoCalcFields が True の場合は OnCalcFields は再帰的に呼び出されることがあるため，データセット（またはマスターリンク関係の一部分の場合はリンクされたデータセット）を変更する操作は実行しないようにします。たとえば，OnCalcFields が Post を実行し，AutoCalcFields が True であれば，OnCalcFields が再び呼び出されて別の Post が実行される，という具合になります。

AutoCalcFields プロパティが False の場合，あるレコードのフィールドの編集中は，OnCalcField は呼び出されません。

OnCalcFields の実行中は，データセットは dsCalcFields モードになり，目的とする計算項目以外の項目の値は設定できません。OnCalcFields イベントが終了すると，データセットは dsBrowse 状態に戻ります。


See also1089045

TDataSet

TDBEdit

TDBLabel

TDBMemo

TDBEdit

データコントロールコンポーネント


Understanding BDE-enabled datasets
Understanding BDE-enabled datasets1090001

Section topics 	参照

この章では，データアクセスにボーランドデータベースエンジン（BDE）を使う Delphi データセットコンポーネントに共通の機能について説明します。BDEの対応は TBDEDataSet（TDataSet の直接の下位コンポーネント）で実装されます。追加のデータベースおよびセッション制御機能は TDBDataSet（TBDEDataSet の直接の下位コンポーネント）で実装されます。

Delphi のデータセットコンポーネント階層

この章では，TBDEDataSet と TDBDataSet のデータセット機能を特に紹介します。TDataSet についてはすでに知っているものと想定しています。TDataSet の下位データセットコンポーネントの一般情報については，「データセットについて」を参照してください。

メモ	TBDEDataSet と TDBDataSet の機能を理解する必要がありますが，独自のカスタム BDE 対応データセットを開発するのでなければ，TBDEDataSet と TDBDataSet をアプリケーションで直接使うことはありません。かわりに，TDBDataSet の直接の下位コンポーネントである TQuery，TStoredProc，TTable を使います。TStoredProc の使い方については，「ストアドプロシージャの操作」を参照してください。TQuery の使い方については，「問い合わせの操作」を参照してください。TTable の使い方については，「テーブルの操作」を参照してください。


Overview of BDE-enablement
Overview of BDE-enablement1090002

Section topics 	参照

TBDEDataSet コンポーネントは，レコードの移動，インデックス，ブックマークを制御する，TDataSet の抽象メソッドを実装します。また，BDE を利用するために TDataSet の仮想メソッドとイベントの多くの再実装も行います。TDataSet 機能の BDE用の実装は，TDataSet で使う場合の一般説明に従います。したがって，その機能についての詳細は，「データセットについて」を参照してください。

すべてのデータセットに共通の機能の BDE 用実装以外に，TBDEDataSet は BLOB 処理，キャッシュアップデート，およびリモートデータベースサーバーとの通信のための新しいプロパティ，イベント，メソッドを導入します。TDBDataSet は，データベース接続の処理およびデータセットと BDE セッションとの関連付けのためのメソッドとプロパティ（メソッドは 1 つ）を導入します。以降の各節では，これらの機能について説明し，その使い方について説明した章の名前が示されています。


Handling database and session connections
Handling database and session connections1090003

Section topics 	参照

TDBDataSet コンポーネントは，データベースとセッションの接続を操作するために次の各プロパティと 1 つの関数（CheckOpen）を導入します。

関数またはプロパティ	用途
CheckOpen 関数	データベースが開いているかどうかを判断する。接続がアクティブであれば True を返し，そうでなければ False を返す
Database プロパティ	データセットが関連付けられているデータベースコンポーネントを表す
DBHandle プロパティ	Database プロパティで指定されたデータベースコンポーネントの BDE データベースハンドルを指定する。直接 BDE API 呼び出しを行う場合のみ使われる
DBLocale プロパティ	Database プロパティで指定されたデータベースコンポーネントの BDE ロケール情報を指定する。直接 BDE API 呼び出しを行う場合のみ使われる
DBSession プロパティ	SessionName プロパティで指定されたセッションコンポーネントの BDE セッションハンドルを指定する。直接 BDE API 呼び出しを行う場合のみ使われる
DatabaseName プロパティ	このデータセットで使われるデータベースの BDE エリアスまたはデータベースコンポーネント名を指定する。データセットが Paradox または dBASE のテーブルの場合，DatabaseName はデータベースのディレクトリ位置を表す絶対パス指定にできる
SessionName プロパティ	このデータセットコンポーネントが関連付けられているセッションを指定する。データベースコンポーネントとセッションコンポーネント両方をデータセットで使う場合，SessionName の設定はデータベースコンポーネントの SessionName プロパティと同じにすべきである
Using the DatabaseName and SessionName properties1090004

以上のプロパティの中でもっともよく使われるのは DatabaseName と SessionName です。Sybase，Oracle，InterBase などのリモートデータベースサーバー上のデータベースを操作する場合，アプリケーションは通常，TDatabase コンポーネントを通してその接続を維持します。各データセットの DatabaseName プロパティは，そのデータセットが使うデータベース接続を確立するデータベースコンポーネントの名前に一致させて設定してください。データベースコンポーネントを使わない場合，DatabaseName は BDE エリアス（または，必要であれば dBASE や Paradox の絶対パス指定）に設定してください。

SessionName は，データセットを関連付ける BDE セッションを表します。明示的なセッションコンポーネントをアプリケーションで使わない場合，このプロパティに値を指定する必要はありません。それは自動で与えられます。アプリケーションで複数のセッションを提供する場合は，データセットの SessionName プロパティを，アプリケーションの適切なセッションコンポーネントの SessionName プロパティに一致させて設定できます。アプリケーションが複数のセッションコンポーネントと 1 つまたは複数のデータベースコンポーネントの両方を使う場合，データセットの SessionName プロパティはそのデータセットが関連付けられているデータベースコンポーネントの SessionName プロパティと一致しなければなりません。

TDatabase でのデータベース接続の処理については，「データベースへの接続」を参照してください。TSession と TSessionList でのセッション管理については，「データベースセッションの管理」を参照してください。

Working with BDE handle properties1090005

データセットコンポーネントの組み込み機能を使わずに BDE に対して API呼び出しを直接行うのでなければ，DBHandle，DBLocale，DBSession の各プロパティを使う必要はありません。これらのプロパティは読み出し専用のプロパティで，データセットが BDE 経由でデータベースサーバーに接続するときにそのデータセットへ自動的に割り当てられます。これらのプロパティは，BDE 関数（その一部はハンドルパラメータを使う）に対して直接 API 呼び出しを行う必要のあるアプリケーション開発者のリソースとして提供されます。BDE API については，オンラインヘルプを参照してください。


Working with a provider component
Working with a provider component1090006

Section topics 	参照

多層データベースアプリケーションにおけるアプリケーションサーバーの一部となる TDBDataSet は Provider プロパティを含みます。Provider は読み出し専用のプロパティで，アプリケーションサーバー上の TProvider コンポーネントが確立する IProvider インターフェースを指します。プロバイダコンポーネントがそのデータの要求元と，クライアントアプリケーション更新の送信先である，アプリケーションサーバー上のデータセットを指定している場合，データセットの Provider プロパティは自動的にそのプロバイダの IProvider インターフェースに設定されます。

TProvider は Delphi Client/Server Suite だけにあります。マルチ階層データベースアプリケーションでのプロバイダコンポーネントの作成と使い方については，「マルチ階層アプリケーションの作成」を参照してください。


Working with cached updates
Working with cached updates1090007

Section topics 	参照

キャッシュアップデートを使うと，データベースからデータを取り出し，そのデータをキャッシュに格納しながらローカルで編集を行い，その後キャッシュされている変更レコードをまとめてデータベースに書き込むことができます。キャッシュアップデートが使用可能な場合，変更の登録やレコード削除などのデータセットへの変更はデータセットの基になるテーブルに直接書き込まれるのではなく，内部キャッシュにまず格納されます。変更が完了すると，アプリケーションはキャッシュされた変更情報をデータベースに書き込むためのメソッドを呼び出し，キャッシュをクリアします。

キャッシュアップデートの実装は TBDEDataSetが行っています。表に，キャッシュアップデートのプロパティ，イベント，メソッドを示します。

プロパティ，イベント，メソッド	用途
CachedUpdates プロパティ	データセットでキャッシュアップデートが有効であるかどうかを判断する。キャッシュアップデートが有効であれば True で，無効ならば False である
UpdateObject プロパティ	問い合わせに基づいてデータセットを更新するために使われる TUpdateSQL コンポーネントの名前を表す
UpdatesPendingプロパティ	データベースに適用する必要のある変更レコードがローカルキャッシュに入っているかどうかを表す。変更レコードがあれば True で，キャッシュが空であれば False である
UpdateRecordTypes プロパティ	キャッシュアップデートの更新レコードの種類を表す
UpdateStatus プロパティ	レコードが，変更されている／いない／挿入された／削除されたかどうかを表す
OnUpdateError イベント	レコード単位で更新エラーを処理するための手続き
OnUpdateRecord イベント	レコード単位で更新を処理するための手続き
ApplyUpdates メソッド	ローカルキャッシュのレコードをデータベースに適用する
CancelUpdates メソッド	データベースに適用せずに保留中のすべての更新をローカルキャッシュから削除する
CommitUpdates メソッド	更新の適用の成功に続いてキャッシュアップデートをクリアする
FetchAll メソッド	編集および更新のためにすべてのデータベースレコードをローカルキャッシュにコピーする
RevertRecord メソッド	まだサーバー側に適用されていなければ，現在のレコードに対する更新を取り消す


Caching BLOBs
Caching BLOBs1090008

Section topics 	参照

TBDEDataSet にある CacheBlobs プロパティは，アプリケーションが BLOB 型レコードを読み出したときに BLOB 型項目が BDE によってローカルにキャッシュへ格納されるかどうかを制御します。デフォルトでは，CacheBlobs は True で，BDE が BLOB 型項目のローカルコピーをキャッシュに格納します。BLOB のキャッシュでは，ユーザーがレコードをいったりきたりしたときにデータベースサーバーから繰り返し BLOBを取り出すのではなく，BDEにより BLOB のローカルコピーを用意することで，アプリケーションの処理効率が向上します。

BLOB がよく更新または置換されるアプリケーションおよび環境で，アプリケーションの処理効率よりも常に最新の BLOB データを表示することの方が重要な場合は，CacheBlobs を False に設定して，アプリケーションに最新の BLOB 型項目が必ず表示されるように指定できます。


Responding to a server yield
Responding to a server yield1090009

Section topics 	参照

TBDEDataSet には，問い合わせの処理中に発生する Sybase サーバー出力へ応答するためのイベントハンドラがあります。問い合わせの処理中に Sybase サーバーが定期的に BDE へ制御を戻す場合，データセットの OnServerYield イベントハンドラがあればそこへ BDE は制御を渡します。そうでなければ，制御はサーバーに直接戻ります。Sybase サーバーは問い合わせ処理中に制御を出力しますが，これは主にアプリケーションが問い合わせ要求を取り消したり更新したりできるようにするためのものです。


See also1090010

TClientDataSet

TDataSet

TBDEDataSet

TProvider

データセットについて

ストアドプロシージャの操作

問い合わせの操作FHXR19911

テーブルの操作

データアクセスコンポーネント


Creating and using a client dataset
Creating and using a client dataset1091001

Section topics 	参照

Delphi はデータベースアプリケーションを作成するためのさまざまな方法をサポートしています。初期の Delphi で開発された従来の 1 階層および 2 階層のクライアント／サーバーアプリケーションに加えて，現バージョンの Delphi は新しいコンポーネント TClientDataSet を使うことにより，さらに以下の 2 つのデータベースモデルをサポートしています。

単一層。このモデルでは，スタンドアロンのアプリケーションがデータをフラットファイルで管理する。このフラットファイルはクライアントデータセットコンポーネントから直接アクセスされる

多層。このモデルでは，クライアントアプリケーションはリモートアプリケーションサーバーによって仲介されたデータのローカルコピーをエンドユーザーが操作できるようにするユーザーインターフェースを提供する。さらに，リモートアプリケーションサーバーはデータベースサーバーと直接通信する

単一層アプリケーションでは，クライアントデータセットコンポーネントは汎用データベースエンジンとして動作し，データをファイルに保存したり，データをファイルからロードしたりします。単一層アプリケーションは，データソースコンポーネントとデータベース対応コントロールを使って，クライアントデータセットとのユーザーインターフェースを提供します。

多層データベースアプリケーションでは，クライアントアプリケーションには，アプリケーションサーバーに対して要求し，このサーバーから受け取ったデータのローカルコピーを操作するクライアントデータセットが含まれます。アプリケーションサーバーは通常はリモートマシン上に存在します。ユーザーはデータソースによってクライアントデータセットに関連付けられたデータベース対応コントロールを通じてデータのローカルコピーを操作します。実際には，クライアントアプリケーションが正しく設計されている場合には，「ブリーフケース」モデルを使うことによって，ユーザーはデータのスナップショットを取り，そのスナップショットをオフラインで操作することもできます。ただし最終的には，クライアントアプリケーションはデータのローカルコピーの変更をアプリケーションサーバーに適用しなければなりません。アプリケーションサーバーはこの変更を実際のデータベースに適用し，エラーがあればクライアントデータセットに処理させるため返します。多層アプリケーションでのブリーフケースモデルの使い方については，「多層アプリケーションの作成」を参照してください。

この章では，単一層と多層のアプリケーションで TClientDataSet コンポーネントを操作する方法について説明します。単一層アプリケーションのクライアントデータセットに適用される説明は，ほとんどすべて多層アプリケーションにも適用されます。多層アプリケーションの場合は，さらに考慮すべき事柄があります。そのいくつかについてはこの章で取り上げますが，詳細については，「多層アプリケーションの作成」に記載されています。

TClientDataSet は TDataSet の下位コンポーネントです。以下の説明では，クライアントデータセットが継承する TDataSet のプロパティ，イベント，メソッドについて理解しているものと想定しています。TDataSet については，「データセットについて」を参照してください。


Working with a client dataset
Working with a client dataset1091002

Section topics 	参照

作成するアプリケーションの各データモジュールには，クライアントデータセットコンポーネントを必要なだけ配置します。データソースコンポーネントを通じてデータベース対応コントロールをクライアントデータセットにリンクする方法は，TDataSet のほかの下位コンポーネントの場合と同様です。


Specifying a data provider
Specifying a data provider1091003

Section topics 	参照

クライアントデータセットは，以下の 3 つのソースのどれからでもデータを取得できます。

別のクライアントデータセット。別のクライアントデータセットからデータを取得する方法については，「データの直接割り当て」を参照

フラットファイル。ファイルからデータを取り出す方法については，「ファイルからデータをロードする」を参照

IProvider インターフェースを使うデータプロバイダオブジェクト

IProvider は ActiveX デュアルインターフェースです。単一層アプリケーションと，ブリーフケースモードで一時的な単一層アプリケーションとして使われるクライアントアプリケーションでは，IProvider インターフェースは定義されません。多層アプリケーションでは通常，RemoteServer プロパティと ProviderName プロパティを使って，クライアントアプリケーションで使用可能なプロバイダインターフェースの中から 1 つを選択します。

RemoteServer はプロバイダリストの取得先の TRemoteServer コンポーネントの名前を指定します。リモートサーバーコンポーネントはクライアントデータセットと同じデータモジュールにあります。リモートサーバーコンポーネントは「データブローカー」とも呼ばれるアプリケーションサーバーへの接続を確立し，維持します。多層アプリケーションでのリモートサーバーコンポーネントの使い方については，「多層アプリケーションの作成」を参照してください。

設計時には，RemoteServer を指定した後，オブジェクトインスペクタで ProviderName プロパティのドロップダウンリストからプロバイダを選択できます。実行時には，コード内に ProviderName を設定することによって，使用可能なプロバイダの中で切り替えができます。


Assiging data directly
Assiging data directly1091004

Section topics 	参照

使用可能な IProvider インターフェースがない場合，クライアントデータセットにデータを割り当てるには，クライアントデータセットの Data プロパティを使います。Data はデータパケット形式の OLE バリアントです。データパケットは別のクライアントデータセットから，またはプロバイダコンポーネントから取得できます。いったんデータパケットが Data に割り当てられると，データソースコンポーネントによってクライアントデータセットに接続されたデータベース対応コントロールにその内容が自動的に表示されます。

プロバイダコンポーネントを使うクライアントデータセットを開くと，データパケットが自動的に Data に割り当てられます。

単一層アプリケーションの場合，データはフラットファイルから取得されます。クライアントアプリケーションでは，フラットファイルまたはアプリケーションサーバー上のプロバイダからデータを取得することができます。ブリーフケースモデルでは通常はフラットファイルから取得します。アプリケーションサーバーからデータを取得する場合，すべてのデータを一度に取り出すか，チャンク単位で取得するかを指定できます。どちらの場合も，受け取るデータパケットには指定したデータが含まれます。

 Loading data from a file1091005

ファイルからデータをロードするには，クライアントデータセットの LoadFromFile 手続きを呼び出します。LoadFromFile は 1 つのパラメータを取ります。データを読み出すファイルを指定する文字列です。ファイル名には，妥当であれば絶対パス名を指定できます。

ファイル内のデータは，クライアントデータセットのデータ形式に従って，そのクライアントデータセットか別のクライアントデータセットが SaveToFile 手続きを使って保存してあるデータでなければなりません。ファイルへのデータの保存については，「ファイルへのデータの保存」を参照してください。

LoadFromFile を呼び出すと，ファイル内のすべてのデータが Data プロパティに読み込まれます。

Requesting data from an application server1091006

多層アプリケーションでは，TClientDataSet の 2 つのプロパティと 1 つのメソッドによって，アプリケーションサーバーからデータを取得する方法が決定されます。

プロパティまたはメソッド	用途
FetchOnDemand プロパティ	クライアントデータセットが必要に応じて自動的にデータを取得するのか，アプリケーションにクライアントデータセットの GetNextPacket 関数を呼び出してもらって追加データを取り出すのかを決定する
PacketRecords プロパティ	各データパケットで返すレコードの種類または数を指定する
GetNextPacket メソッド	アプリケーションサーバーから次のデータパケットを取得する
デフォルトでは，クライアントデータセットがすべてのレコードをアプリケーションサーバーから取り出します。PacketRecords と FetchOnDemand を使って，データをどのように取り出すかを制御できます。

PacketRecords は一度に取得するレコードの数か，返すレコードの種類を指定します。デフォルトでは，PacketRecords は -1 に設定されます。これは，アプリケーションが最初に起動したとき，またはアプリケーションが明示的に GetNextPacket を呼び出したときに，使用可能なすべてのレコードが一度に取得されることを意味します。PacketRecords が -1 の場合，クライアントデータセットが最初にデータを取得すると，使用可能なレコードをすべて取得したことになるので，それ以上データを取得する必要はなくなります。

レコードを少数単位で取得するには，PacketRecords に取得するレコードの数を設定します。たとえば，次の文は各データパケットのサイズを 10 レコードに設定します。

ClientDataSet1.PacketRecords := 10;

PacketRecords が 0 より大きい場合，クライアントデータセットは必要に応じて GetNextPacket を呼び出してデータを取得します。新たに取得されたパケットは，すでにクライアントデータセット内にあるデータの最後に追加されます。

GetNextPacket は取得したレコードの数を返します。戻り値が PacketRecords と同じ場合，使用可能なレコードの終わりに到達しなかったことを意味します。戻り値が 0 より大きく，PacketRecords より小さい場合，取得操作の間に最終レコードに到達したことを意味します。GetNextPacket によって 0 が返された場合，取得するレコードがそれ以上存在しないことを意味します。

PacketRecords を使ってアプリケーションサーバーからデータベースについてのメタデータ情報を取得することもできます。メタデータ情報を取り出すには，PacketRecords を 0 に設定します。

メモ	レコードの自動取得は FetchOnDemand プロパティによって制御されます。FetchOnDemand が True（デフォルト）の場合，自動取得が可能になります。必要に応じてレコードの自動取得を禁止するには，FetchOnDemand を False に設定します。FetchOnDemand が False の場合，アプリケーションは GetNextPacket を明示的に呼び出してレコードを取得しなければなりません。

Making data read-only1091007

ユーザーがデータを変更できないようにするには，クライアントデータセットの ReadOnly プロパティを True に設定します。ReadOnly を True に設定すると，CanModify プロパティが False に設定されます。

参考	ほかの種類のデータセットとは異なり，クライアントデータセットの読み出し専用状態を変更するためにこのデータセットを閉じる必要はありません。アプリケーションは ReadOnly プロパティの現在の設定を変更するだけで，いつでも一時的にクライアントデータセットを読み出し専用にしたり，これを取り消したりできます。

Navigating through data1091008

アプリケーションが標準のデータベース対応コントロールを使う場合，ユーザーはクライアントデータセットのレコード間をほかのデータセットの場合と同様に移動することができます。プログラムによってレコード間を移動することも可能で，その場合は First，GotoKey，Last，Next，Prior などの標準データセットメソッドを使います。これらのメソッドについては，オンラインヘルプを参照してください。

クライアントデータセットは RecNo プロパティを使うことによって，データセット内の特定のレコードにカーソルを置くこともできます。通常，アプリケーションは現在のレコードのレコード番号を調べるために RecNo を使います。アプリケーションは RecNo に特定のレコード番号を設定することによって，そのレコードを現在のレコードにすることができます。

アプリケーションはブックマークを使って特定のレコードをマークし，そのレコードへ移動することもできます。ブックマークの使い方については，「データセットについて」を参照してください。

最後に，使用可能なデータの一部だけをユーザーに提示するよう一時的に制限するため，アプリケーションは範囲とフィルタを使えます。範囲またはフィルタを適用する場合，クライアントデータセットはすべてのデータを取得しますが，範囲またはフィルタの条件を満たすデータだけを表示します。フィルタの使い方については，「データセットについて」を参照してください。範囲については，「テーブルの操作」を参照してください。


Editing data
Editing data1091009

Section topics 	参照

データベース対応コントロールを使って実行時にユーザーがレコードを編集できるようにしたり，プログラムによってレコードを編集したりできます。編集が行われる場合，挿入，削除，変更の内容は Data プロパティには格納されず，内部的な変更ログに格納されます。ただし変更ログが意図的に使用不可にされている場合を除きます。変更ログに格納された編集内容は，アプリケーションによって削除または破棄されるまで，変更ログに残ります。

Counting changed records1091010

ChangeCount プロパティは変更ログ内の現在の変更レコード数を示します。ChangeCount が 0 の場合，ログ内に記録された変更内容はありません。

Disabling logging of changes1091011

LogChanges プロパティを使うと，ロギングを一時的に停止できます。LogChanges が True の場合，変更内容はログに記録されます。LogChanges が False の場合，変更内容は記録されません。単一層アプリケーションでは，次の節で説明するような複数レベルでの元に戻す操作は不要なので，変更ログを使用不可にできます。

Undoing changes one at a time1091012

レコードのオリジナルバージョンが変更されないまま Data に残っていたとしても，ユーザーがレコードを編集し，そのレコードを離れ，再びそのレコードに戻るたびに，最後に変更したバージョンのレコードがユーザーに対して表示されます。ユーザーまたはアプリケーションが 1 つのレコードを何度も編集した場合，それぞれの変更バージョンのレコードが変更ログ内に別々のエントリとして格納されます。

1 つのレコードに対するそれぞれの変更内容を格納することによって，レコードの以前の状態を復元する必要が生じた場合に，複数レベルでの元に戻す操作をサポートすることが可能になります。レコードに対する最後の変更内容を削除するには，UndoLastChange を呼び出します。UndoLastChange は論理パラメータ FollowChange を取ります。このパラメータは，復元されたレコード上にカーソルを再配置するか（True），現在のレコード上にカーソルを置いたままにするか（False）を指示します。1 つのレコードに対して複数の変更がある場合，UndoLastChange を呼び出すたびに編集内容が 1 つずつ削除されます。UndoLastChange は変更内容の削除が成功したか失敗したかを示す論理値を返します。削除が成功した場合，UndoLastChange によって True が返されます。

Undoing all changes to a single record1091013

1 つのレコードに対する変更内容を 1 つずつ削除するかわりに，すべての変更を一度に削除できます。1 つのレコードに対する変更内容をすべて削除するには，レコードを選択した後，RevertRecord を呼び出します。RevertRecord は現在のレコードに対するすべての変更内容を変更ログから削除します。

Removing all changes in the change log1091014

変更ログに記録されたすべての変更内容を破棄するには，CancelUpdates を呼び出します。CancelUpdates は変更ログをクリアし，すべてのレコードに対するすべての編集内容を完全に破棄します。CancelUpdates を呼び出す場合には注意が必要です。CancelUpdates を呼び出した後は，ログ内に存在していた変更内容は回復できなくなります。


Merging changes into Data
Merging changes into Data1091015

Section topics 	参照

単一層アプリケーションでクライアントデータセットを使う場合，データを編集すると，変更内容が変更ログに記録されますが，それらの変更内容はデータのオリジナルバージョンには影響を及ぼしません。

このような場合，変更内容を確定するには，MergeChangeLog を呼び出して，変更ログ内の変更バージョンのレコードを Data にマージします。MergeChangeLog は，変更ログ内のすべての変更項目値で Data のレコードを上書きします。

メモ	アプリケーションサーバーに接続されたクライアントアプリケーションでは MergeChangeLog を呼び出さないでください。この場合は，ApplyUpdates を呼び出して変更内容をデータベースに書き込みます。詳細については，「データベースへの更新の適用」を参照してください。

MergeChangeLog を実行した後，Data には変更ログに存在していたすべての変更内容と既存のデータを合成したデータが含まれます。この合成データが Data の新たな基礎となり，これに対してそれ以降の変更が可能になります。MergeChangeLog によってすべてのレコードの変更ログがクリアされ，ChangeCount プロパティが 0 にリセットされます。


Applying updates to the database
Applying updates to the database1091016

Section topics 	参照

クライアントデータセットが多層データベースアプリケーションのクライアントアプリケーション部分で使われる場合，クライアントデータセットによって記録される変更内容は，アプリケーションサーバーを通じてデータベースに適用されるまで，クライアント上にだけ存在します。クライアントデータセットの変更内容をデータベースに適用するには，クライアントデータセットの ApplyUpdates メソッドを呼び出します。ApplyUpdates は変更ログの変更内容を取り出し，アプリケーションサーバーにデータパケットとして送信します。このデータパケットは Delta と呼ばれます。

ApplyUpdates は 1 つのパラメータ MaxErrors を取ります。MaxErrors は整数で，更新プロセスを取り消すまでの許容エラー数を示します。MaxErrors が 0 の場合，アプリケーションサーバー上で更新エラーが発生すると，ただちに更新プロセス全体が中止されます。データベースには変更内容がまったく書き込まれず，クライアントデータセットの変更ログは元のまま残されます。MaxErrors が -1 の場合，エラーはいくつでも許容され，変更ログには正常に適用できなかったレコードがすべて含まれます。MaxErrors が正の値で，MaxErrors で許容される数よりも多くのエラーが発生した場合，すべての更新が中断されます。発生したエラー数が MaxErrors で指定された数より少ない場合，正常に適用されたすべてのレコードがクライアントデータセットの変更ログから自動的にクリアされます。

ApplyUpdates は更新内容をデータベースに書き込むために Reconcile 関数を呼び出します。Reconcile はエラー処理ルーチンで，アプリケーションサーバー上のプロバイダコンポーネントの ApplyUpdates 関数を呼び出します。プロバイダコンポーネントの ApplyUpdates 関数は実際に更新内容をデータベースに書き込み，エラーを検出した場合はその修正を試みます。エラー条件のために適用できないレコードは，クライアントデータセットの Reconcile メソッドに送り返されます。Reconcile は OnReconcileError イベントハンドラを呼び出すことによって，残されたエラーの修正を試みます。エラーを修正するための OnReconcileError イベントハンドラを記述しておかなければなりません。OnReconcileError の作成と使い方については，「多層アプリケーションの作成」を参照してください。

最後に，Reconcile は正常に適用された変更内容を変更ログから削除し，Data を更新して新たに更新されたレコードを反映させます。Reconcile が完了すると，ApplyUpdates は発生したエラーの数を報告します。


Saving data to a file
Saving data to a file1091017

Section topics 	参照

単一層アプリケーションでクライアントデータセットを使う場合，データを編集しマージするとき，変更内容はメモリにだけ存在します。変更内容を確定してレコードにするためには，SaveToFile メソッドを使ってそれらの変更内容をディスクに書き込まなければなりません。

SaveToFile は 1 つのパラメータを取ります。データを書き込むファイルを指定する文字列です。ファイル名には，妥当であれば絶対パス名を指定できます。指定したファイルがすでに存在する場合，そのファイルの現在の内容がすべて上書きされます。

単一層アプリケーションの場合，データをファイルに保存することによって更新プロセスが完了します。ブリーフケースモデルをサポートするクライアントアプリケーションの場合，ファイルをディスクに書き込むことが更新プロセスの第一段階となります。ディスク上のデータは，最終的には，アプリケーションサーバー上のプロバイダを通じてデータベースサーバーに適用されなければなりません。通常この処理は，アプリケーションサーバーにネットワーク接続されているクライアントアプリケーションを再実行し，アプリケーションサーバーへのリンクを確立し，ディスクからファイルをロードし，ApplyUpdates を呼び出してディスクデータをデータベースサーバーに書き込むことによって行われます。ブリーフケースモデルの使い方およびアプリケーションサーバーを使った変更内容のマージについては，「多層アプリケーションの作成」を参照してください。


Sorting and indexing
Sorting and indexing1091018

Section topics 	参照

クライアントデータセットを多層アプリケーションで使う場合，アプリケーションサーバーから受信するデータに基づいて，デフォルトのインデックスとソート順が継承されます。デフォルトインデックスは DEFAULT_ORDER と呼ばれます。この順序付けは使えますが，デフォルトインデックスの変更や削除はできません。

デフォルトインデックスのほかに，クライアントデータセットは別のインデックスを保持します。このインデックスは CHANGEINDEX と呼ばれ，変更ログ（Delta プロパティ）に格納された変更レコードを対象とします。CHANGEINDEX は，Delta 内のすべてのレコードについて，これらがデータセット内の全レコードセットに含まれた場合に出現する順序に順序付けします。CHANGEINDEX は DEFAULT_ORDER から継承したものと同じ順序付けに基づきます。DEFAULT_ORDER の場合と同様に，CHANGEINDEX の変更や削除はできません。

データセットにほかの既存のインデックスを使ったり，自分自身でインデックスを作成することもできます。以降の各節では，クライアントデータセットに対してインデックスを作成/使用する方法について説明します。


Adding a new index
Adding a new index1091019

Section topics 	参照

クライアントデータセットに新しいインデックスを作成するには，AddIndex を呼び出します。AddIndex は 3 つのパラメータを取ります。作成するインデックスの名前，インデックスを構成する既存のキー設定項目のリスト，およびインデックスオプションセットの 3 つです。

参考	クライアントデータセットでは，内部的に計算される項目を使ってインデックス付けとソートができます。

作成するインデックスは，マシンの場所に応じて，昇順のアルファベット順にソートされます。このデフォルトを無効にするには，インデックスオプションパラメータで ixDescending をオプションセットに追加します。

インデックスの文字列項目をソートする場合，デフォルトでは大文字と小文字が区別されます。ソートするとき大文字と小文字の区別を無視するには，インデックスオプションパラメータに ixCaseInsensitive を追加します。


Deleting an index
Deleting an index1091020

Section topics 	参照

クライアントデータセットに作成したインデックスを削除するには，DeleteIndex を呼び出し，削除するインデックスの名前を指定します。DEFAULT_ORDER インデックスと CHANGEINDEX インデックスは削除できません。


Switching among indexes
Switching among indexes1091021

Section topics 	参照

複数のインデックスが使用可能な場合に，クライアントデータセットで別のインデックスを使うには，IndexName プロパティを使って目的のインデックスを選択します。設計時には，オブジェクトインスペクタで IndexName プロパティのドロップダウンボックスに表示される使用可能インデックスの中から選択できます。


Indexing on the fly
Indexing on the fly1091022

Section topics 	参照

クライアントデータセットの一部になるインデックスを作成するかわりに，一時的なインデックスを迅速に作成できます。この場合，インデックス付けに使う項目を IndexFieldNames プロパティに指定することによって作成します。項目名はセミコロンで区切ります。このリストで指定する項目名の順序は重要な意味を持ちます。


Working with another view of a dataset
Working with another view of a dataset1091023

Section topics 	参照

TClientDataSet は指定したクライアントデータセットを実行時に別のビューで操作できるようにする CloneCursor 手続きを提供します。CloneCursor は元のクライアントデータセットのデータを共有する別のクライアントデータセットを提供します。

CloneCursor は 2 つのパラメータを取ります。Source はコピーするクライアントデータセットを指定します。Reset は現在ソースデータセットで有効な範囲またはフィルタをコピーするかどうかを指定します。Reset が False の場合，コピーされたクライアントデータセットが開くと，元のデータセットで有効な範囲またはフィルタはすべてコピーでもアクティブになります。現在の範囲およびフィルタを適用せずにクライアントデータセットのコピーを作成するには，Reset に True を指定します。たとえば，次の文によって ClientDataSet1 がコピーされますが，範囲もフィルタもコピーには適用されません。

ClientDataSet2.CloneCursor(ClientDataSet1, True);


Creating a new dataset
Creating a new dataset1091024

Section topics 	参照

実行時にクライアントデータセットを迅速に作成するには，TClientDataSet の CreateDataSet 手続きを使います。

データセットを作成する手順は次のとおりです。

1.	クライアントデータセットの FieldDefs プロパティに新しい項目定義を指定します。

2.	クライアントデータセットの IndexDefs プロパティに新しいインデックス定義を設定します。

3.	CreateDataSet を呼び出します。この手続きは新しいデータセットを構築します。


See also1091025

TClientDataSet

TDataSet

TProvider

データセットについて

ストアドプロシージャの操作

問い合わせの操作

テーブルの操作

データアクセスコンポーネント


Working with data sources
Working with data sources1092001

Section topics 	参照

この章では，データセットとフォーム上のデータベース対応ビジュアルコントロールコンポーネントを仲介する TDataSource コンポーネントについて説明します。

データセットにはそれぞれ，対応するデータソースコンポーネントが必要です。データソースコンポーネントは，フォーム上のビジュアルデータベースコントロールをデータセットにリンクします。ビジュアルデータベースコントロールはデータソースコンポーネントからデータを受け取り，データソースコンポーネントにデータを送ります。データソースコンポーネントはデータセットからのデータをビジュアルコントロールに伝え，逆にビジュアルコントロールからのデータをデータセットに送り返します。


Establishing a database-to-data control link
Establishing a database-to-data control link1092002

Section topics 	参照

TDataSource コンポーネントは，データセットとフォーム上のデータベース対応コンポーネントを仲介する非ビジュアルデータベースコンポーネントです。データベース対応コンポーネントは，データセットの基になるデータの表示，操作，編集を可能にします。フォーム上のデータベース対応コントロールにデータの表示や処理を行うには，すべてのデータセットをデータソースコンポーネントに関連付けなければなりません。同様に，データを表示したり処理するには，データベース対応コントロールもそれぞれデータソースコンポーネントに関連付ける必要があります。また，データセットをマスターリンク関係でリンクするのにもデータソースコンポーネントが使えます。

ほかの非ビジュアルデータベースコンポーネントを追加するのと同じように，データソースコンポーネントもデータモジュールやフォームに追加できます。データモジュールやフォームの各データセットコンポーネントについて最低 1 つのデータソースコンポーネントを追加する必要があります。


Using TDataSource properties
Using TDataSource properties1092003

Section topics 	参照

TDataSource のプロパティは数種類しかありません。以降の各節で，主要なプロパティの内容と，設計時および実行時にそれらのプロパティを設定する方法について説明します。

Setting the DataSet property1092004

DataSet プロパティは，データソースコンポーネントのデータの取得元になるデータセットの名前を指定するのに使います。設計時にオブジェクトインスペクタのドロップダウンリストからデータセットを選択できます。実行時には，必要であればデータソースコンポーネント用のデータセットを切り替えられます。たとえば次のコードは，CustSource データソースコンポーネント用のデータセットを Customers と Orders の間で切り替えます。

with CustSource do

begin

if DataSet = 'Customers' then

DataSet := 'Orders'

else

DataSet := 'Customers';

end;

DataSet プロパティを別のフォーム上のデータセットに対して設定し，2 つのフォーム上のデータコントロールの同期をとることもできます。次に例を示します。

procedure TForm2.FormCreate (Sender : TObject);

begin

DataSource1.Dataset := Form1.Table1;

end;

Setting the Name property1092005

Name プロパティは，アプリケーションのほかのすべてのデータソースと区別できるようにデータソースコンポーネントに意味のある名前を指定するのに使います。データソースコンポーネントに付けた名前はデータモジュールのコンポーネントアイコンの下に表示されます。

一般にデータソースコンポーネントには，関連するデータセットを示す名前を付ける必要があります。たとえば Customers というデータセットがあるとします。そのデータセットにデータソースコンポーネントをリンクするには，データソースコンポーネントの DataSet プロパティに「Customers」を設定します。このデータセットとデータソースの接続を明確にするには，データソースコンポーネントの Name プロパティに「CustomersSource」などを設定する必要があります。

Setting the Enabled property1092006

Enabled プロパティはデータソースコンポーネントがそのデータセットに接続されているかどうかを決めます。Enabled プロパティが True の場合，そのデータソースはデータセットに接続されています。

Enabled プロパティを False に設定すれば，単一のデータソースを一時的にデータセットから切断できます。Enabled が False の場合，データソースコンポーネントに結び付いたすべてのデータコントロールは空白になり，Enabled が True になるまで非アクティブになります。ただし，データセットコンポーネントの DisableControls メソッドおよび EnableControls メソッドを使ってデータセットへのアクセスを制御することをお勧めします。これらのメソッドは結び付けられたすべてのデータソースに影響を及ぼすからです。

Setting the AutoEdit property1092007

TDataSource の AutoEdit プロパティは，データセットにリンクしたデータベース対応コントロールにユーザーが入力を開始したときに，データソースに接続されたデータセットが自動的に編集状態になるかどうかを指定します。AutoEdit が True（デフォルト）の場合，リンクされたデータベース対応コントロールにユーザーが入力するとデータセットは自動的に編集状態になります。それ以外の場合は，アプリケーションが明示的に Edit メソッドを呼び出したときにだけデータセットは編集状態になります。データセットの状態については，「データセットの状態の決定と設定」を参照してください。


Using TDataSource events
Using TDataSource events1092008

Section topics 	参照

TDataSource のイベントには関連する 3 つのイベントハンドラがあります。

OnDataChange

OnStateChange

OnUpdateData

Using the OnDataChange event1092009

OnDataChange イベントは，カーソルが新規レコードに移るたびに呼び出されます。アプリケーションが Next，Previous，Insert やカーソル位置を変えるその他のメソッドを呼び出すと，OnDataChange イベントが発生します。

このイベントは，アプリケーションがコンポーネントの同期を手動で保持している場合に使います。

Using the OnUpdateData event1092010

OnUpdateData イベントは，現在のレコードのデータを更新する際に呼び出されます。たとえば OnUpdateData イベントが発生するのは，Postが呼び出された後で，データが実際にデータベースに登録される前です。

このイベントは，アプリケーションが標準の（データベース対応でない）コントロールを使っているためにデータセットとの間で同期を保持する必要がある場合に使います。

Using the OnStateChange event1092011

OnStateChange イベントは，データソースのデータセットの状態が変わるたびに呼び出されます。データセットの State プロパティは現在の状態を記録しています。OnStateChange イベントは，TDataSource の状態が変化したときに操作する場合に使います。

たとえば，通常のデータベースセッションの進行中はデータセットの状態が頻繁に変化します。この変化を追跡するには，フォーム上のラベルに現在のデータセットの状態を表示するイベントハンドラ OnStateChange を記述します。次のコードはそうしたルーチンの記述例です。このコードは実行時に，データセットの State プロパティの現在の設定を表示し，設定が変わるたびに更新します。

procedure TForm1.DataSource1.StateChange(Sender:TObject);

var

S:String;

begin

case CustTable.State of

dsInactive: S := 'Inactive';

dsBrowse: S := 'Browse';

dsEdit: S := 'Edit';

dsInsert: S := 'Insert';

dsSetKey: S := 'SetKey';

end;

CustTableStateLabel.Caption := S;

end;

同様に，現在の状態に基づいてボタンやメニュー項目の使用可能と使用不可を切り替える場合にも OnStateChange が使えます。

procedure Form1.DataSource1.StateChange(Sender: TObject);

begin

CustTableEditBtn.Enabled := (CustTable.State = dsBrowse);

CustTableCancelBtn.Enabled := CustTable.State in [dsInsert, dsEdit, dsSetKey];

...

end;


See also1092012

TDataSource

データセットについて

データセットの状態の決定と設定

データアクセスコンポーネント


Working with field components
Working with field components1093001

Section topics 	参照

この章では，TField オブジェクトとその下位オブジェクトで共通のプロパティ，イベント，およびメソッドついて説明します。TField の下位オブジェクトはデータセットの個々のデータベース列を表します。また，下位項目コンポーネントを使ってアプリケーションでの表示を制御してデータを編集する方法についても説明します。

アプリケーションで TField コンポーネントを直接使うことは決してありません。デフォルトでは，アプリケーションにデータセットを初めて入れそれを開くときに，TField の下位コンポーネント（これは動的なデータ型固有のコンポーネントで，データベーステーブル内の各列を表す）が自動的に割り当てられます。設計時には，項目エディタを呼び出して Delphi のデフォルト値にかわる持続的項目を作成することによって動的項目のデフォルトをオーバーライドできます。

表に，下位項目コンポーネントの各型と，その標準的な目的および該当する場合はその許容範囲値を示します。

コンポーネント名	用途
TAutoIncField	-2, 147, 483, 648～ 2, 147, 483, 647 の範囲の整数。Paradox で使用する場合，項目の値は自動的にインクリメントされる
TBCDField	固定小数点数を持つ実数。精度は 18 桁。範囲は小数点以下の桁による
TBlobField	バイナリデータ。理論上の最大サイズは 2GB
TBooleanField	True または False
TBytesField	バイナリデータ。最大サイズは 255 バイト
TCurrencyField	5.0×10e-324～ 1.7×10e308 の範囲の実数。Paradox で使用する場合，項目は小数点以下 2 桁の精度を持つ
TDateField	日付
TDateTimeField	日付と時刻
TFloatField	5.0×10e-324～ 1.7×10e308 の範囲の実数
TIntegerField	-2, 147, 483, 648～ 2, 147, 483, 647 の範囲の整数
TMemoField	テキストデータ。理論上の最大は 2GB
TNumericField	3.4×10e-4932～ 1.1×10e4932 の範囲の実数
TSmallintField	-32, 768～ 32, 768 の範囲の整数
TStringField	文字列データ。最大サイズはヌルターミネータも含めて 8192 バイト
TTimeField	時刻
TVarBytesField	バイナリデータ。最大サイズは 255 バイト
TWordField	0～ 65, 535 の範囲の整数
この章では，すべての項目コンポーネントが TField から継承するプロパティとメソッドについて説明します。多くの場合，TField は下位オブジェクトがオーバーライドする標準機能を宣言または実装します。いくつもの下位オブジェクトがオーバーライドされた機能を共有している場合は，その機能についてもこの章で説明しています。個々の項目コンポーネントについての詳細は，オンラインヘルプの「VCL リファレンス」を参照してください。


Understanding field components
Understanding field components1093002

Section topics 	参照

すべての Delphi データアクセスコンポーネントと同じように，項目コンポーネントも非ビジュアルです。項目コンポーネントは設計時にも直接表示されることはありません。かわりに項目コンポーネントはデータセットコンポーネントと関連付けられ，TDBEdit や TDBGrid などのデータベース対応コンポーネントがそのデータセットを経由してデータベース列にアクセスできるように機能します。

一般的には，単一の項目コンポーネントがデータベース項目内の単一の列の特性（そのデータ型やサイズ）を表します。その上，揃え方，表示形式，編集形式などの Delphi 表示特性も表します。最後に，データセット内のレコード間のスクロール時には，項目コンポーネントは現在のレコード内のその項目の値を表示および変更できるようにもします。たとえば TFloatField コンポーネントには，そのデータの外観に直接影響する 4 つのプロパティがあります。

コンポーネント名	用途
Alignment	データの位置合わせを左揃え，中央揃え，右揃えのいずれにするかを指定
DisplayWidth	コントロールに表示する桁数を指定
DisplayFormat	表示用のデータ形式を指定（表示する小数点の桁数など）
EditFormat	編集中の値の表示方法を指定
項目コンポーネントには DisplayWidth や Alignment など，多くの共有プロパティがありますが，TFloatField の Precision のようにデータ型に固有のプロパティもあります。こうしたプロパティはそれぞれ，フォーム上でのデータの表示形式，つまりアプリケーションユーザーにデータがどう見えるかに影響します。Precision などの一部のプロパティは，ユーザーによりコントロールに入力されたデータがデータセットの基になるテーブルにどう書き戻されるかにも影響することがあります。

データセットのすべての項目コンポーネントは動的である（データベーステーブルの基本構造に基づいて自動生成される）か，持続的である（項目エディタで設定した特定の項目名とプロパティに基づいて生成される）かのどちらかになります。動的項目と持続的項目は異なる長所を持ち，異なる種類のアプリケーションにそれぞれ適しています。以降の各節では，動的項目と持続的項目について詳細に説明し，どちらを選択するかの助言を与えています。


Dynamic field components
Dynamic field components1093003

Section topics 	参照

動的に生成された項目コンポーネントが Delphi のデフォルトです。実際どのデータセットでも，すべての項目コンポーネントは，初めてデータセットをデータモジュールに入れてそのデータセットをデータベースに関連付け，そしてそれを開いたときに，動的コンポーネントとして始まります。項目コンポーネントは，データセットがアクセスする 1 つまたは複数のデータベーステーブル内の列の基本的な物理特性に基づいて自動生成された場合は動的になります。基になるテーブルまたは問い合わせの各列にそれぞれ 1 つの項目コンポーネントが生成されます。基になるデータベーステーブルの各列に作成される TField の正確な下位コンポーネントは，ボーランドデータベースエンジン（BDE）から受け取った項目型情報によって決まります。項目コンポーネントの型は，そのプロパティと，その項目に関連付けられたデータがフォーム上のデータベース対応コントロールでどう表示されるかを決めるものです。動的項目は一時的なもので，データセットが開いている間だけ存在します。

動的項目を使うデータセットを再度開くたびに，そのデータセットの基になるデータベーステーブルの現在の構造に基づいて，完全に新しい動的項目コンポーネントセットがデータセットに対して構築し直されます。それらのデータベーステーブルの列が変更された場合は，動的項目コンポーネントを使うデータセットを次に開いたときに，生成される項目コンポーネントもそれに合わせて変更されます。

データの表示や編集に関して柔軟でなければならないアプリケーション内では動的項目を使います。たとえば，SQL エクスプローラのようなデータベース探索ツールを作成するには，各データベーステーブルで列数や列の型が異なるため，動的項目を使わなければなりません。ユーザーが行うデータとの対話がほとんどグリッドコンポーネント内部で起こり，しかもアプリケーションが使うデータベーステーブルが頻繁に変更されるとわかっているようなアプリケーション内でも，動的項目を使うと便利です。

アプリケーション内で動的項目を使う手順は次のとおりです。

1.	データセットとデータソースをデータモジュールに入れます。

2.	データセットをデータベーステーブルおよび問い合わせに関連付け，データソースをデータセットに関連付けます。

3.	データベース対応コントロールをアプリケーションのフォームに入れ，データモジュールを各フォームのユニットのそれぞれの uses 節に追加し，各データベース対応コントロールをデータモジュール内のデータソースに関連付けます。

4.	データセットを開きます。

使いやすさを別にして，動的項目は限定的になる可能性があります。コードを記述しないことには，動的項目の表示および編集のデフォルト設定を変更することができず，動的項目の表示順序を安全に変更することができず，データセットの項目へのアクセスを防止することもできません。データセットに追加の項目（計算項目や参照項目）を作成することはできず，動的項目のデフォルトのデータ型をオーバーライドすることもできません。データベースアプリケーション内の項目を制御して柔軟に扱えるようにするには，項目エディタを呼び出してデータセットに持続的項目コンポーネントを作成する必要があります。


Persistent field components
Persistent field components1093004

Section topics 	参照

デフォルトでは，データセット項目は動的です。そのプロパティと利用可能性は自動的に設定されるもので，変更は不可能です。設計時または実行時に項目の可視特性つまり表示特性を設定および変更でき，データセット内の既存の項目に基づいて新しい項目を作成でき，あるいはデータ入力を検証できるように項目のプロパティとイベントに対する制御を可能にするには，データセットに対し持続的項目を作成しなければなりません。

設計時には項目エディタを使って，アプリケーションのデータセットで使われる項目コンポーネントの持続的リストを作成できるので，このエディタを使ってください。項目コンポーネントの持続的リストはアプリケーションに格納され，たとえデータセットの基になるデータベースの構造が変化してもこのリストは変化しません。データセットのすべての項目は持続的か動的かのどちらかです。

持続的項目コンポーネントを作成すると，以下のようなことができるようになります。

データセットから参照できる項目を，元になるデータベースの一部の項目に限定する

項目コンポーネントを持続的コンポーネントのリストに追加する

基になるデータベースの特定の項目へのアクセスを防止するため，持続的コンポーネントのリストから項目コンポーネントを除去する

データセットの元になるテーブルや問い合わせに基づいて，新しい項目を定義する。これは，既存の項目を置換するために使われる

データセットのほかの項目に基づいて値が計算される計算項目を定義する

ほかのデータセットの項目に基づいて値が計算される参照項目を定義する

項目コンポーネントの表示プロパティと編集プロパティを変更する

持続的項目は，項目エディタに指定した項目名およびプロパティに基づき生成された項目です。項目エディタでいったん持続的項目を作成した後は，その項目に対し，データ値の変更に応答するイベントハンドラやデータ入力を検証するイベントハンドラも作成できます。

メモ	データセットに持続的項目を作成する場合，選択した項目だけが設計時および実行時にアプリケーションで利用可能です。設計時には，いつでも項目エディタで［項目の追加(A)］を選択してデータセットの持続的項目について追加と削除ができます。

単一のデータセットが使用する項目はすべて持続的または動的のいずれかになります。項目の種類を組み合わせることは 1 つのデータセットではできません。データセットに対して持続的項目を作成した後で，それを動的項目に変更したい場合は，データセットからすべての持続的項目を削除しなくてはなりません。動的項目についての詳細は，「動的項目コンポーネント」を参照してください。

メモ	持続的項目の主要な用途の 1 つは，データの表示と外観を制御できるようにすることです。ほかにもデータの外観を制御する方法はあります。たとえば，データディクショナリを使って項目属性を項目コンポーネントに割り当てることができます。また，データベース対応グリッドの列の外観も制御できます。データディクショナリについての詳細は，「項目コンポーネントのデータディクショナリ属性セットの作成」を参照してください。グリッドでの列の外観を制御する方法については，「グリッドの操作」を参照してください。


Creating persistent fields
Creating persistent fields1093005

Section topics 	参照

項目エディタで作成された持続的項目コンポーネントは，基礎にあるデータに対して効率的で読み出しやすい，型保障されたアクセスを提供します。持続的項目コンポーネントを使うと，アプリケーションを実行するたびに，基礎になるデータベースの物理構造が変更されている場合でも，同じ列と同じ順番を使って表示することが保障されます。特定な項目に依存するデータベース対応のコンポーネントとプログラムコードは希望したように動作します。持続的項目コンポーネントを基にした列が削除または変更されると，存在しない列や不一致なデータに対してアプリケーションを実行せずに，例外が生成されます。

データセットに持続的項目を作成する手順は次のとおりです。

1.	データセットをデータモジュールに入れます。

2.	そのデータセットの DatabaseName プロパティを設定します。

3.	TableName プロパティ（TTable の場合）または SQL プロパティ（TQuery の場合）を設定します。

4.	データモジュール内のデータセットコンポーネントをダブルクリックして項目エディタを呼び出します。

項目エディタには，タイトルバー，レコード操作ボタン，リストボックスがあります。

項目エディタのタイトルバーには，データセットの入っているデータモジュールかフォームの名前と，データセット名そのものが表示されます。たとえば CustomerData データモジュールの Customers というデータセットを開くと，タイトルバーには「CustomerData.Customers」と表示されます。

タイトルバーの下にはレコード操作ボタンがあります。これらのボタンは，設計時にアクティブなデータセットでレコードを 1 つずつスクロールしたり，最初のレコードや最後のレコードへ移動するのに使います。データセットがアクティブでない場合や空の場合は，レコード操作ボタンは淡色表示になります。

リストボックスにはデータセットの持続的項目コンポーネントの名前が表示されます。新しいデータセットで最初に項目エディタを呼び出したときにリストが空のままなのは，そのデータセットの項目コンポーネントが静的ではなく動的だからです。すでに持続的項目コンポーネントを持っているデータセットで項目エディタを呼び出した場合は，リストボックスに項目コンポーネント名が表示されます。

5.	項目エディタのコンテキストメニューから［項目の追加(A)］を選択します。

6.	静的にする項目を［項目の追加］ダイアログボックスで選択します。デフォルトでは，このダイアログボックスが表示されたときにすべての項目が選択されています。選択した項目が持続的項目になります。

最後に［OK］ボタンを押すと，［項目の追加］ダイアログボックスは閉じ，選択した項目が項目エディタのリストボックスに表示されます。項目エディタのリストボックスの項目は静的です。データセットがアクティブであれば，リストボックスの上にある次のレコードボタンと最後のレコードボタンのレコード操作ボタンが使用可能になることにも注意してください。

その後は，データセットを開くたびに元になるデータベースの各列に対して動的な項目コンポーネントが作成されることはありません。かわりに，指定した項目に対する静的コンポーネントが作成されるだけです。

データセットを開くたびに，計算項目でない持続的項目がそれぞれ存在するかどうか，あるいはデータベースのデータを使ってそうした項目を作成できるかどうかが照合されます。照合できなければ例外が生成され，その項目が有効でないためデータセットを開くことができないと警告が出されます。


Arranging the order of persistent fields
Arranging the order of persistent fields1093006

Section topics 	参照

持続的項目コンポーネントが項目エディタのリストボックスに表示される順序は，データベース対応のグリッドコンポーネントにそれらの項目が表示される順序と同じデフォルトの順序です。リストボックスの項目をドラッグアンドドロップして項目の順序を変更できます。

項目の順序を変える手順は次のとおりです。

1.	項目を選択します。一度に 1 つまたは複数の項目を選択して並べ替えることができます。

2.	選択した項目を新しい位置にドラッグします。

連続していない項目を同時に選択して新しい位置にドラッグすると，それらは連続したブロックとして挿入されます。ブロック内での項目間の順序は変わりません。

別の方法として，項目を選択した後〔Ctrl〕+〔↑〕と〔Ctrl〕+〔↓〕を使ってリスト内の個々の項目の順序を変更する方法もあります。


Defining new persistent fields
Defining new persistent fields1093007

Section topics 	参照

既存のデータセット項目を持続的項目に作成する方法以外に，特別な持続的項目をデータセットに追加として，または別の持続的項目の置き換えとして作成できます。次の表に作成できる追加項目の種類を示します。

項目の種類	用途
Data	既存項目を置き換える（たとえば，データ型を変更するにはテーブルの列かまたは基礎になるデータセットの問い合わせに従う）
Calculated	データセットの OnCalcFields イベントハンドラが実行時に計算した値を表示する
InternalCalc	クライアントデータセットが実行時に計算してデータとともに格納した値を表示する
Lookup	指定されたデータセットから指定検索条件で値を検索する
以上の持続的項目は表示だけを目的とします。データの内容はデータベースのどこかにすでに存在しているか，または一時的に存在するだけなので，実行時には保持されていません。データセットの基になるテーブルとデータの物理的構造はいずれにしても変更されません。

新しい持続的項目コンポーネントを作成するには，項目エディタのコンテキストメニューを呼び出して［項目の新規作成(N)］を選択します。［項目の新規作成］ダイアログボックスが表示されます。

［項目の新規作成］ダイアログボックスには，［項目のプロパティ］，［項目の種類］，［参照の定義］という 3 つのグループボックスがあります。

［項目の種類］ラジオグループは，新しく作成する項目コンポーネントの種類を指定するのに使います。デフォルトの種類は［データ(D)］です。［参照(L)］を選択すると，［参照の定義］グループボックスで［データセット(A)］と［キー項目(K)］の 2 つの編集ボックスが使用可能になります。計算項目を作成することもでき，TClientDataset コンポーネントを操作している場合はさらに InternalCalc 項目も作成できます。

［項目のプロパティ］グループボックスは一般的な項目コンポーネントの情報を入力するのに使います。コンポーネントの項目名を［名前(N)］編集ボックスに入力します。ここで入力する名前は，その項目コンポーネントの FieldName プロパティに対応しています。この名前を使って［コンポーネント(C)］編集ボックスにコンポーネント名が構築されます。［コンポーネント(C)］編集ボックスに表示される名前は，項目コンポーネントの Name プロパティに対応しており，その目的は情報の提供だけです。Name プロパティはソースコード中で項目コンポーネントを識別するためにのみ使われます。［コンポーネント(C)］編集ボックスに直接入力してもその内容は破棄されます。

［項目のプロパティ］グループの［型(T)］コンボボックスは，項目コンポーネントのデータ型を指定するのに使います。新しく作成する項目コンポーネントには必ずデータ型を指定しなければなりません。たとえばある項目に浮動小数点の通貨値を表示するには，ドロップダウンリストから［Currency］を選択します。［サイズ(S)］編集ボックスは，文字列項目への表示または入力が可能な最大文字数を指定したり，Bytes 項目と VarBytes 項目のサイズを指定するのに使います。それ以外のすべてのデータ型では，［サイズ(S)］を指定しても意味がありません。

［参照の定義］グループボックスを使うのは参照項目を作成する場合だけです。詳細は「参照項目を定義する」を参照してください。


Defining a data field
Defining a data field1093008

Section topics 	参照

データ項目はデータセットの既存の項目を置換します。たとえば，プログラム上の理由で TSmallIntField を TIntegerField に置換するとします。項目のデータ型を直接変更することはできないため，置換に使う項目を新しく定義しなければなりません。

重要	新しい項目を定義して既存の項目を置換する場合でも，定義する項目のデータ値はデータセットの基になるテーブルの既存の列から取得しなければなりません。

［項目の新規作成］ダイアログボックス内にデータ項目を作成する手順は次のとおりです。

1.	データセットに割り当てられている持続的項目のリストから目的の項目を削除し，コンテキストメニューで［新規項目の定義］を選択します。

2.	［名前(N)］編集ボックスにデータセットの項目の名前を入力します。新しい項目名は入力しないでください。ここでは，新しい項目が値を取り出す元になるデータセットの項目の名前を指定します。

3.	［型(T)］コンボボックスから項目の新しいデータ型を選択します。選択するデータ型は置換する項目のデータ型とは別にする必要があります。文字列項目を，サイズの異なる文字列項目に置換することはできません。データ型は異なっている必要がありますが，基になっているテーブルにおける実際の項目型は互換性を持つものでなければならない点に注意してください。

4.	必要であれば［サイズ(S)］編集ボックスに項目のサイズを入力します。TStringField，TBytesField，TVarBytesField という 3 つの型の項目の場合に必要となります。

5.	未選択であれば［項目の種類］ラジオグループの［データ(D)］を選択します。

6.	［OK］を選択します。［項目の新規作成］ダイアログボックスは閉じ，手順の 1 で指定した既存の項目は新しく定義したデータ項目で置換されます。データモジュールまたはフォームの type 宣言にあるコンポーネント宣言は更新されます。

項目コンポーネントに関連したプロパティやイベントを編集するには，項目エディタのリストボックスのコンポーネント名を選択し，オブジェクトインスペクタでプロパティやイベントを編集します。項目コンポーネントのプロパティやイベントの編集についての詳細は，「持続的項目のプロパティとイベントを設定する」を参照してください。


Defining a calculated field
Defining a calculated field1093009

Section topics 	参照

計算項目は，実行時にデータセットのイベントハンドラ OnCalcFields が計算した値を表示します。たとえば，ほかの項目値と結合した値を表示する文字列項目を作成できます。

［項目の新規作成］ダイアログボックスに計算項目を作成する手順は次のとおりです。

1.	［名前(N)］編集ボックスに計算項目名を入力します。既存の項目名は入力しないでください。

2.	［型(T)］コンボボックスから項目のデータ型を選択します。

3.	必要であれば［サイズ(S)］編集ボックスに項目のサイズを入力します。サイズの入力が必要なのは TStringField，TBytesField，TVarBytesField という 3 つの型の項目だけです。

4.	［項目の種類］ラジオグループの［計算項目(C)］を選択します。

5.	［OK］を選択します。新しく定義された計算項目は，自動的に項目エディタのリストボックスの持続的項目リストの最後に追加され，コンポーネントの宣言が自動的にソースコードのフォームの type 宣言に追加されます。

6.	データセットのイベントハンドラ OnCalcFields に項目値を計算するコードを記述します。項目値を計算するコードの記述についての詳細は，「計算項目のプログラミング」を参照してください。

メモ	項目コンポーネントに関連したプロパティやイベントを編集するには，項目エディタのリストボックスのコンポーネント名を選択し，オブジェクトインスペクタでプロパティやイベントを編集します。項目コンポーネントのプロパティやイベントの編集についての詳細は，「持続的項目のプロパティとイベントを設定する」を参照してください。

クライアントデータセットまたは問い合わせコンポーネントを操作している場合は，InternalCalc 項目も作成できます。計算項目の場合と同じように，内部的な計算項目を作成してプログラミングします。クライアントデータセットでは，両者の計算項目間での重大な違いは，InternalCalc 項目用に計算される値がクライアントデータセットのデータの一部として格納されたり取り出される点です。InternalCalc 項目を作成するには，［項目の種類］グループで［InternalCalc］ラジオボタンを選択します。


Programming a calculated field
Programming a calculated field1093010

Section topics 	参照

計算項目を定義した後にその項目値を計算するコードを記述しなければなりません。そうしないと値は必ずヌル値になります。計算項目のコードはデータセットの OnCalcFields イベントに追加されます。

計算項目の値をプログラミングする手順は次のとおりです。

1.	オブジェクトインスペクタのドロップダウンリストからデータセットコンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページを選択します。

3.	OnCalcFields プロパティをダブルクリックしてデータセットコンポーネントの CalcFields 手続きを呼び出すか作成します。

4.	計算項目の値やその他のプロパティを設定するコードを記述します。

たとえば，データモジュール CustomerData のテーブル Customers に CityStateZip という計算項目を作成したとします。CityStateZip は，会社が存在する都市，州，郵便番号を 1 行でデータベース対応コントロールに表示する必要があります。

Customers テーブルの CalcFields 手続きにコードを追加するには，オブジェクトインスペクタのドロップダウンリストから Customers テーブルを選択して［イベント］ページに切り替えて OnCalcFields プロパティをダブルクリックします。

TCustomerData.CustomersCalcFields 手続きがユニットのソースコードウィンドウに表示されます。項目を計算する手続きに次のコードを追加します。

CustomersCityStateZip.Value := CustomersCity.Value + ', ' + CustomersState.Value
   + ' ' + CustomersZip.Value;


Defining a lookup field
Defining a lookup field1093011

Section topics 	参照

参照項目は書き込み禁止項目で，実行時に検索条件に基づいて値を表示します。もっとも簡単な形式では，既存の検索項目名，検索する項目値，値を表示する参照データセットの別項目の 3 つを参照項目に渡します。

たとえば，通信販売のアプリケーションの場合，オペレータは参照項目を使って，顧客から受け取った郵便番号に対応する都市と州を自動的に決められます。この場合，検索対象の列は ZipTable.Zip と呼ばれ，検索する値は Order.CustZip に入力される顧客の郵便番号です。戻り値は，ZipTable.Zip が Order.CustZip 項目の現在の値と照合するレコードの ZipTable.City と ZipTable.State という 2 つの列の値です。

［項目の新規作成］ダイアログボックス内で参照項目を作成する手順は次のとおりです。

1.	参照項目名を［名前(N)］編集ボックスに入力します。既存の項目名は入力しないでください。

2.	［型(T)］コンボボックスから項目のデータ型を選択します。

3.	必要であれば［サイズ(S)］編集ボックスに項目のサイズを入力します。サイズの入力が必要なのは TStringField，TBytesField，TVarBytesField という 3 つの型の項目だけです。

4.	［項目の種類］ラジオグループの［参照(L)］を選択します。［参照(L)］を選択すると［データセット(A)］と［キー項目(K)］という 2 つのコンボボックスが使用可能になります。

5.	［データセット(A)］コンボボックスのドロップダウンリストから項目値参照の対象となるデータセットを選択します。参照のデータセットは，項目コンポーネントそのもののデータセットとは別でなければなりません。そうでないと実行時に循環参照の例外が生成されます。参照のデータセットを指定すると［参照側のキー(U)］と［値を返す項目(R)］の 2 つのコンボボックスが使用可能になります。

6.	［キー項目(K)］ドロップダウンリストから値の照合基準になる現在のデータセットの項目を選択します。複数の項目で照合するには，ドロップダウンリストの選択ではなく，直接項目名を入力します。複数の項目名を指定する場合は各項目名をセミコロンで区切ります。

7.	［参照側のキー(U)］ドロップダウンリストから手順の 6 で指定した［キー項目(K)］項目を基準に比較するための参照データセットの項目を選択します。複数の項目を指定するには，項目名を直接入力します。複数の項目名を指定する場合は各項目名をセミコロンで区切ります。

8.	［値を返す項目(R)］ドロップダウンリストから，作成する参照項目の値として返す参照データセットの項目を選択します。参照データセット内の複数の項目の値を返すには，項目名を直接入力します。

アプリケーションを設計して実行する場合，参照項目の値は計算項目の値が計算される前に決まります。計算項目は参照項目に基づくことができますが，参照項目が計算項目に基づくことはできません。LookupCache プロパティを使うとこの動作を効果的なものにできます。LookupCache は，データセットを初めて開いたときに参照項目の値がメモリにキャッシュされるのか，あるいはデータセットの現在のレコードが変更されるたびに参照項目の値が動的に参照されるのかを決めます。

LookupDataSet が変化しそうになく，別個の参照値の数が少ない場合に参照項目の値をキャッシュするには，LookupCache を True に設定します。DataSet を開いたときに各 LookupKeyFields 値集合に参照値が事前にロードされるので，参照値のキャッシングにより処理効率の高速化が望めます。DataSet の現在のレコードが変化した場合，項目オブジェクトは LookupDataSet にアクセスするのではなくキャッシュでその Value を探すことができます。この処理効率の向上は，LookupDataSet が低速アクセスのネットワーク上にあるときに特に顕著です。

参考	参照値のキャッシングは，シングル階層アプリケーションでクライアントデータセットを操作している場合に特に役立つ可能性があります。このようなアプリケーションは LookupCache を True に設定して，別のデータセットからではなくプログラミングによって参照値を与えることができます。

DataSet の各レコードで KeyFields の値がそれぞれ異なる場合，キャッシュで値を見つけようとすることのオーバーヘッドは，キャッシュによって得られるどの処理効率アップよりも大きくなる可能性があります。このオーバーヘッドは，KeyFields が受け取ることのできる別個の値の数が多くなるほど大きくなります。

LookupDataSet が揮発性の場合，参照値のキャッシングにより不正確な結果が生じることがあります。参照キャッシュの値を更新するには，RefreshLookupList を呼び出します。RefreshLookupList は LookupList プロパティを再生成します。LookupList プロパティには，各 LookupKeyFields 値集合の LookupResultField の値が入っています。

実行時に LookupCache を設定する場合は，RefreshLookupList を呼び出してキャッシュを初期化します。


Deleting persistent field components
Deleting persistent field components1093012

Section topics 	参照

持続的項目コンポーネントを削除することは，テーブル中の利用可能な列の一部にアクセスするときや，独自の持続的項目を定義してテーブル中の列を置き換えるときに役立ちます。

データセットの 1 つまたは複数の持続的項目コンポーネントを削除する手順は次のとおりです。

1.	項目エディタのリストボックスで削除対象の項目を選択します。

2.	〔Del〕を押します。

メモ	コンテキストメニューを呼び出して［削除(D)］を選択しても目的の項目を削除できます。

削除した項目はもうデータセットが利用できなくなっており，データベース対応コントロールによって表示することはできません。間違って削除した持続的項目コンポーネントはいつでも再作成することができますが，そのプロパティまたはイベントに対してそれより前に行っていた変更はすべて失われます。詳細は「持続的項目の作成」を参照してください。

メモ	データセットのすべての持続的項目コンポーネントを削除した場合は，データセットの基になっているデータベーステーブルの各列に対し，動的項目コンポーネントが再び自動生成されます。


Setting persistent field properties and events
Setting persistent field properties and events1093013

Section topics 	参照

設計時に，持続的項目コンポーネントのプロパティを設定したり，イベントをカスタマイズできます。プロパティは，データベース対応コンポーネントでの項目の表示方法を制御します。たとえば，その項目を TDBGrid に表示できるかどうかや，項目値を変更できるかどうかなどを制御します。イベントは，項目内のデータの取り出し，変更，設定，検証時の動作を制御します。

項目コンポーネントのプロパティを設定したり，そのイベントハンドラをカスタマイズして記述するには，項目エディタのコンポーネントを選択するか，オブジェクトインスペクタでコンポーネントリストから選択します。


Setting display and edit properties at design time
Setting display and edit properties at design time1093014

Section topics 	参照

選択した項目コンポーネントの表示プロパティを編集するには，オブジェクトインスペクタウィンドウの［プロパティ］ぺージに切り替えます。表に編集可能な表示プロパティを示します。

プロパティ	用途
Alignment	データベース対応コントロール内の項目内容を左揃え，右揃え，または中央揃えにする
Calculated	True の場合，実行時に項目値は CalcFields メソッドで計算される False の場合（デフォルト），項目値は現在のレコードから決まる
Currency	数値項目のみ。True の場合，数値項目は金額として表示される False の場合（デフォルト），数値項目は金額として表示されない
DisplayFormat	データベース対応コンポーネントでのデータの表示形式を指定する
DisplayLabel	データベース対応グリッドコンポーネントでの項目の列名を指定する
DisplayWidth	項目を表示するグリッド列の幅を文字数で指定する
EditFormat	データベース対応コンポーネントでのデータの編集形式を指定する
EditMask	編集可能項目のデータ入力を指定された型と文字の範囲に限定し，項目内に表示される特殊な編集不可能文字（ハイフン，カッコなど）を指定する
FieldName	項目の値とデータ型の取得元になるテーブルの列の実際の名前を指定する
Index	データセット内の項目の順序を指定する
MaxValue	数値項目のみ。ユーザーがその項目に入力できる最大値を指定する
MinValue	数値項目のみ。ユーザーがその項目に入力できる最小値を指定する
Name	項目コンポーネントのコンポーネント名を指定する
ReadOnly	True の場合，データベース対応コンポーネントに項目値を表示するが，編集はできない。 False の場合（デフォルト），項目値の表示と編集を許可する
Size	文字列項目への表示や入力が可能な最大文字数，あるいは TBytesField 項目や TVarBytesField 項目のサイズをバイト数で指定する
Tag	プログラマが必要であればすべてのコンポーネントで使える 32 ビット整数型の項目
Visible	True の場合（デフォルト），項目はデータベース対応グリッドコンポーネントに表示される。 False の場合，項目はデータベース対応グリッドコンポーネントに表示されない。ユーザー定義のコンポーネントは，このプロパティに基づいて表示するかどうかを決定できる
すべての項目コンポーネントですべてのプロパティが使えるとは限りません。たとえば，TStringField 型の項目コンポーネントには，Currency，MaxValue，DisplayFormat の各プロパティはありません。また，TFloatField 型のコンポーネントには Size プロパティはありません。

ほとんどのプロパティは，設定がそのまま表示に反映されますが，Calculated のようなプロパティには追加のプログラミングが必要です。また，DisplayFormat，EditFormat，EditMask のように相互関係のあるプロパティでは，相互に設定値を調節しなければなりません。DisplayFormat，EditFormat，EditMask の使い方についての詳細は，「ユーザー入力の制御とマスク」を参照してください。


Setting field component properties at run time
Setting field component properties at run time1093015

実行時に項目コンポーネントのプロパティを使ったり操作することができます。たとえば，次のコードは Customers テーブルの CityStateZip 項目の ReadOnly プロパティを True に設定します。

CustomersCityStateZip.ReadOnly := True;

また，次の文は Customers テーブルの CityStateZip 項目の Index プロパティを 3 に設定することで項目順を変更します。

CustomersCityStateZip.Index := 3;


Creating attribute sets for field components
Creating attribute sets for field components1093016

Section topics 	参照

データセット内でアプリケーションが使っているいくつかの項目が，Alignment，DisplayWidth，DisplayFormat，EditFormat，MaxValue，MinValue などの形式プロパティを共有する場合，まず単一の項目に対してそれらのプロパティを設定し，それからプロパティを属性セットとしてデータディクショナリに保存すると使いやすくなります。データディクショナリに保存された属性セットはほかの項目に簡単に適用できます。

データセットの項目コンポーネントに基づいて属性セットを作成する手順は次のとおりです。

1.	データセットをダブルクリックして項目エディタを呼び出します。

2.	プロパティの設定対象になる項目を選択します。

3.	オブジェクトインスペクタで項目の希望のプロパティを設定します。

4.	項目エディタのリストボックスを右クリックしてコンテキストメニューを呼び出します。

5.	［属性の上書き保存(S)］を選択して現在の項目のプロパティ設定を属性セットとしてデータディクショナリに保存します。

属性セットの名前のデフォルトは現在の項目の名前です。別の名前を指定するには，コンテキストメニューの［属性の上書き保存(S)］ではなく，［属性に名前を付けて保存(E)］を選択してください。

メモ	SQL エクスプローラから属性セットを直接作成することもできます。データディクショナリから属性セットを作成した場合，その集合はどの項目にも適用されませんが，その中に 2 つの追加属性を指定できます。1 つは TFloatField や TStringField などの項目型で，もう 1 つは属性セットに基づく項目がフォーム上にドラッグされたときに自動的にフォーム上に追加される TDBEdit や TDBCheckBox などの SQL 対応コントロールです。詳細はデータベースエクスプローラのオンラインヘルプを参照してください。


Associating attribute sets with field components
Associating attribute sets with field components1093017

Section topics 	参照

データセットでアプリケーションが使っている数個の項目が，Alignment，DisplayWidth，DisplayFormat，EditFormat，MaxValue，MinValue などの形式プロパティを共有しており，それらのプロパティ設定を属性セットとしてデータディクショナリに保存した場合，各項目の設定を手作業でやり直さなくても，簡単にその属性セットを項目に適用できます。さらに，データディクショナリの属性の設定を後で変更した場合，次に項目コンポーネントがデータセットに追加されたときにその変更は属性セットに関連するすべての項目に対して自動的に適用されます。

属性セットを項目コンポーネントに適用する手順は次のとおりです。

1.	データセットをダブルクリックして項目エディタを呼び出します。

2.	属性セットの適用対象となる項目を選択します。

3.	コンテキストメニューを呼び出して［属性の関連付け(O)］を選択します。

4.	［属性の関連付け］ダイアログボックスを使って，適用する属性セットを選択するか入力します。データディクショナリに現在の項目と同じ名前の属性セットがある場合，その集合の名前が編集ボックスに表示されます。

重要	データディクショナリの属性セットが後日変更された場合は，それを使う各項目コンポーネントにその属性セットを再度適用しなければなりません。項目エディタを呼び出して，属性の再適用先であるデータセット内の項目コンポーネントを複数選択することができます。


Removing attribute associations
Removing attribute associations1093018

Section topics 	参照

属性セットと項目の関連付けを取り消す場合は，次の手順に従って関連付けを解除できます。

1.	対象項目を持つデータセットで項目エディタを呼び出します。

2.	属性の関連付けの解除対象になる項目を 1 つまたは複数選択します。

3.	項目エディタのコンテキストメニューを呼び出して［Unassociate Attributes］を選択します。

重要	属性セットの関連付けを解除しても項目プロパティは変更されません。項目は属性セット適用時の設定を保持しています。これらのプロパティを変更するには，項目エディタで項目を選択してそのプロパティをオブジェクトインスペクタで設定します。


Controlling and masking user input
Controlling and masking user input1093019

Section topics 	参照

EditMask プロパティは，TStringField，TDateField，TTimeField，TDateTimeField の各コンポーネントに関連するデータベース対応コンポーネントへユーザーが入力できる値の型と範囲を制御するための方法を与えます。既存のマスクを使うことも，独自のマスクを作成することもできます。編集マスクを使ったり作成する一番簡単な方法は，入力マスクエディタを使う方法です。ただし，オブジェクトインスペクタで EditMask 項目に直接マスクを入力することもできます。

メモ	TStringField コンポーネントの場合，EditMask プロパティがその表示形式にもなります。

項目コンポーネントの入力マスクエディタを呼び出す手順は次のとおりです。

1.	項目エディタまたはオブジェクトインスペクタでコンポーネントを選択します。

2.	オブジェクトインスペクタの［プロパティ］ページをクリックします。

3.	オブジェクトインスペクタの EditMask プロパティの値列をダブルクリックするか，省略記号のボタンをクリックして入力マスクエディタを開きます。

［入力マスク(I)］編集ボックスは，マスク形式の作成や編集に使います。［例(S)］リストボックスは定義済みマスクの選択に使います。サンプルマスクを選択すると［入力マスク(I)］編集ボックスにそのマスク形式が表示され，そこで形式を変更したりそのまま使ったりできます。［テスト(T)］編集ボックスでは，マスクについて許されるユーザー入力をテストできます。

［マスク(M)］ボタンを使うと，マスクのカスタムセット（作成してある場合）を［例(S)］リストボックスにロードして選択できるようにします。


Using default formatting for numeric, date, and time fields
Using default formatting for numeric, date, and time fields1093020

Section topics 	参照

Delphi に組み込まれている表示と編集の形式を設定するルーチンは，TFloatField，TCurrencyField，TIntegerField，TSmallIntField，TWordField，TDateField，TDateTimeField，TTimeField の各コンポーネントにデフォルトの形式を与えるインテリジェント機能を備えています。これらのルーチンを使うために必要な操作は特にありません。

デフォルトの形式は表のルーチンで設定されます。

ルーチン	対象
FormatFloat	TFloatField, TCurrencyField
FormatDateTime	TDateField, TTimeField, TDateTimeField
FormatCurr	TCurrencyField
与えられたコンポーネントで使えるのは，項目コンポーネントのデータ型と一致した形式プロパティだけです。

日付，時刻，通貨，数値についてデフォルトの形式を設定するときの規則は Windows95 のコントロールパネルにある［地域］の設定に基づきます。たとえば日本のデフォルト設定では，TFloatField 列の Currency プロパティを True に設定した場合，1234 という値は \1234 と表示されます。

設計時または実行時に，項目コンポーネントの DisplayFormat プロパティと EditFormat プロパティを編集してその項目のデフォルトの表示設定を変更できます。また，イベントハンドラの OnGetText と OnSetText を記述して，実行時に項目コンポーネントの形式をカスタマイズすることもできます。実行時に項目コンポーネントのプロパティを設定する方法についての詳細は，「実行時に項目コンポーネントのプロパティを操作する」を参照してください。


Handling events
Handling events1093021

Section topics 	参照

ほかの Delphi コンポーネントと同じように，項目コンポーネントには関連したイベントハンドラがあります。データベース対応コントロール経由で項目に入力されたデータに影響するイベントを制御するには，こうしたイベントハンドラを記述します。表に項目コンポーネントに関連するイベントの一覧を示します。

イベント	用途
OnChange	項目の値が変化すると呼び出される
OnGetText	表示や編集用に項目コンポーネントの値を取り出すと呼び出される
OnSetText	項目コンポーネントの値を設定すると呼び出される
OnValidate	編集や挿入により値が変更されると，項目コンポーネントの値を検証するために呼び出される
OnGetText イベントや OnSetText イベントは主に，Delphi に組み込まれている形式設定の機能より一歩進んだカスタム対応の形式設定を実行したいときに使います。OnChange イベントは，メニューやビジュアルコントロールの使用可能と使用不可の切り替えなど，データの変更に関連するアプリケーション固有のタスクを実行するのに使います。OnValidate イベントは，データベースサーバーに値を返す前にアプリケーションでデータ入力の検証を制御したいときに使います。

項目コンポーネントのイベントハンドラを記述する手順は次のとおりです。

1.	コンポーネントを選択します。

2.	オブジェクトインスペクタの［イベント］ページを選択します。

3.	イベントハンドラの値列をダブルクリックしてソースコードウィンドウを表示します。

4.	ハンドラのコードを作成または編集します。


Working with field component methods at runtime
Working with field component methods at runtime1093022

Section topics 	参照

実行時に使える項目コンポーネントのメソッドは，項目の値のデータ型を変換する場合や，項目コンポーネントに関連付けられたフォーム上の最初のデータベース対応コントロールにフォーカスを設定する場合に使います。

アプリケーションが BeforePost などのデータセットイベントハンドラでレコード指向のデータ検証をする場合，項目に関連付けられたデータベース対応コンポーネントのフォーカスを制御することは重要です。関連付けられたデータベース対応コントロールにフォーカスがあるかどうかに関係なく，レコードの中の項目を検証できます。レコード内のある特定の項目の検証に失敗した場合，異常データを含むデータベース対応コントロールにフォーカスを移してユーザーが誤りを修正できるように設定することが可能です。

項目の FocusControl メソッドを使ってその項目のデータベース対応コンポーネントに対するフォーカスを制御します。FocusControl メソッドは，フォーム上のある項目に関連付けられた最初のデータベース対応コントロールにフォーカスを設定します。項目を検証する前にイベントハンドラは項目の FocusControl メソッドを呼び出す必要があります。次のコードは，Customers テーブルの Company 項目に対して FocusControl メソッドを呼び出す方法を示しています。

CustomersCompany.FocusControl;

表に，項目コンポーネントのメソッドの一部とその用途を示します。メソッドの完全なリストと各メソッドの使い方についての詳細は，オンラインヘルプの「VCL リファレンス」で TField とその下位コンポーネントのエントリを参照してください。

メソッド	用途
AssignValue	項目の種類に基づいた自動変換関数を使って項目値を指定値に設定する
Clear	項目をクリアして nil に設定する
GetData	項目から形式設定されていないデータを取得する
IsValidChar	データベース対応のコントロールにユーザーが入力した文字がこの項目に対して有効かどうかを決定する
SetData	形式設定されていないデータをこの項目に割り当てる


Displaying, converting, and accessing field values
Displaying, converting, and accessing field values1093023

Section topics 	参照

TDBEdit や TDBGrid などのデータベース対応コントロールは，項目コンポーネントに関連付けられた値を自動的に表示します。データセットとコントロールで編集が可能であれば，データベース対応コントロールはデータベースに新しい値や変更した値を送ることもできます。一般に，データベース対応コントロールに組み込まれたプロパティやメソッドは，プログラムを追加作成せずにデータセットへの接続，値の表示や更新ができます。データベースアプリケーションで使えるときはいつでも，これらのプロパティやメソッドを使ってください。データベース対応コントロールについての詳細は，第 12 章「データコントロールの使い方」を参照してください。

標準のコントロールは，項目コンポーネントに関連付けられたデータベース値の表示や編集ができます。ただし標準のコントロールを使うには追加のプログラミング作業が必要なことがあります。


Displaying field component values in standard controls
Displaying field component values in standard controls1093024

Section topics 	参照

アプリケーションは，項目コンポーネントの Value プロパティを使ってデータベースの列値にアクセスできます。たとえば次の文は，CustomersCompany 項目の値を TEdit コントロールのテキストに代入します。

Edit3.Text := CustomersCompany.Value;

このメソッドは文字列値に対しては正しく機能しますが，ほかのデータ型では変換を処理するために追加のプログラミング作業が必要なことがあります。項目コンポーネントには，このような変換を処理するための関数が組み込まれています。

メモ	項目値へのアクセスとその設定にはバリアントも使えます。バリアントは柔軟性のある新しいデータ型です。バリアントを使った項目値へのアクセスとその設定方法についての詳細は，「デフォルトのデータセットメソッドを使った項目値へのアクセス」を参照してください。


Converting field values
Converting field values1093025

Section topics 	参照

変換関数はあるデータ型を別のデータ型に変換しようと試みます。たとえば AsString 関数は数値と論理値を文字列表現に変換します。表に項目コンポーネントの変換関数の一覧と，項目コンポーネントの種類別に使用可能な関数を示します。

関数	TStringField	TIntegerField	TSmallintField	TWordField	TFloatField	TCurrencyField	TBCDField	TDateTimeField	TDateField	TTimeField	TBooleanField	TBytesField	TVarBytesField	TBlobField	TMemoField	TGraphicField
AsVariant	○	○	○	○	○	○	○	○	○	○	○	○	○	○	○	○
AsString		○	○	○	○	○	○	○	○	○	○	○	○	○	○	○
AsInteger	○				○	○	○
AsFloat	○	○	○	○				○	○	○
AsCurrency	○	○	○	○				○	○	○
AsDateTime	○
AsBoolean	○
AsVariant メソッドはすべてのデータ型間の変換に使えます。不安があるときは AsVariant を使うといいでしょう。

変換ができない場合もあります。たとえば AsDateTime を使って文字列を日付，時刻，日付／時刻の各形式に変換できるのは，文字列値が認識できる日付／時刻形式になっている場合だけです。変換が失敗すると例外が生成されます。

また，常に希望する変換結果が得られるとは限りません。たとえば，TDateTimeField の値を AsFloat で浮動小数点形式に変換する場合は，項目の日付の部分は 1899 年 12 月 31 日以降の日数に，また時刻の部分は 24 時間を単位とする小数に変換されます。表に許容されてはいるが特殊な結果をもたらす変換例を示します。

変換	結果
文字列から論理値	「True」，「False」，「Yes」，「No」を論理値に変換する。それ以外の場合は例外を生成する
浮動小数点形式から 整数	浮動小数点値をもっとも近い整数値に丸める
日付／時刻形式から 浮動小数点形式	日付を 1899 年 12 月 31 日以降の日数に変換し，時間を 24 時間を単位とする小数に変換する
論理値から文字列	論理値を「True」または「False」に変換する
変換がまったくできないこともあります。このとき変換を試みるとやはり例外が生成されます。

変換関数の使い方はコンポーネントに属するメソッドの使い方と似ています。つまり，関数名を代入文のどこかにあるコンポーネント名の最後に追加します。変換が行われるのは必ず，実際の代入が実行される前です。たとえば，次の文は CustomersCustNo 項目の値を文字列に変換し，その文字列を編集コントロールのテキストに代入します。

Edit1.Text := CustomersCustNo.AsString;

逆に次の文は，編集コントロールのテキストを整数として CustomersCustNo 項目に代入します。

MyTableMyField.AsInteger := StrToInt(Edit1.Text);

実行時にサポートされていない変換を実行すると例外が発生します。


Accessing field values with the default dataset method
Accessing field values with the default dataset method1093026

Section topics 	参照

項目値へのアクセスには，デフォルトのデータセットメソッド FieldValues をバリアントと一緒に使うといいでしょう。たとえば次の文は，編集ボックスの値を Customers テーブルの CustNo 項目に入力します。

Customers['CustNo'] := Edit2.Text;

FieldValues はデータセットのデフォルトのメソッドなので，メソッド名を明示的に指定する必要はありません。ただし，次の文は前述の文とまったく同じに使えます。

Customers.FieldValues['CustNo'] := Edit2.Text;

バリアントについての詳細は，『Object Pascal 言語リファレンス』を参照してください。


Accessing field values with a dataset's Fields property
Accessing field values with a dataset's Fields property1093027

Section topics 	参照

データセットコンポーネントの Fields プロパティを使用すると，項目の値にアクセスできます。Fields プロパティで項目値にアクセスするのが役立つのは，多くの列の繰り返し処理や，設計時に使えないテーブルの操作をする場合です。

Fields プロパティを使うには，データセット内の項目の順序とデータ型がわかっていなければなりません。アクセスする項目の指定には順序数を使います。データセットの最初の項目には 0 という番号が付きます。項目値は，必要であればその項目コンポーネントの変換関数で変換しなければなりません。項目コンポーネントの変換関数についての詳細は，「項目コンポーネントの変換関数を使う」を参照してください。

たとえば次の文は，Customers テーブルの 7 番目の列（Country）の現在の値を編集コントロールに代入します。

Edit1.Text := CustTable.Fields[6].AsString;

逆にデータセットの Fields プロパティが指定する項目に値を代入できます。次に例を示します。

begin

  Customers.Edit;

  Customers.Fields[6].AsString := Edit1.Text;

  Customers.Post;

end;


Accessing field values with a dataset's FieldByName method
Accessing field values with a dataset's FieldByName method1093028

Section topics 	参照

項目値のアクセスには，データセットの FieldByName メソッドも使えます。このメソッドは，アクセスしたい項目名はわかっているが，設計時に基になるテーブルにアクセスできない場合に使います。

FieldByName メソッドを使うには，アクセスしたい項目の名前とデータセットがわかっていなければなりません。項目名を引数としてメソッドへ渡します。項目値へのアクセスや，項目値の変更には，AsString や AsIntger などの適切な項目コンポーネント変換関数を使って結果を変換します。たとえば次の文は，Customers データセットの CustNo 項目の値を編集コントロールに代入します。

Edit2.Text := Customers.FieldByName('CustNo').AsString;

逆に値を項目に代入することもできます。

begin

  Customers.Edit;

  Customers.FieldByName('CustNo').AsString := Edit2.Text;

  Customers.Post;

end;


Checking a field's current value
Checking a field's current value1093029

Section topics 	参照

アプリケーションが TClientDataSet を使う場合やアプリケーションサーバー上の TProvider コンポーネントのソースデータセットであるデータセットを管理する場合にレコードの更新が困難なときは，CurValue プロパティを使って問題を引き起こしているレコードの項目値を検査できます。CurValue はデータベースのほかのユーザーが加えた変更を含む項目コンポーネントの現在値を表します。

データベースへの値の登録時に問題が発生した場合に項目値を検査するには CurValue を使います。現在の項目値が，データベースへのその値の登録時にキー違反などの問題を引き起こしていれば，OnReconcileError が発生します。OnReconcileError イベントハンドラでは，NewValue は問題を引き起こした未登録の値で，OldValue は編集前の項目に元々割り当てられていた値で，CurValue は項目に現在割り当てられている値です。CurValue は，OldValue の読み出し後に別のユーザーがその項目の値を変更した場合，OldValue とは異なることがあります。


Setting a default value for a field
Setting a default value for a field1093030

Section topics 	参照

DefaultExpression プロパティを使って，項目のデフォルト値を実行時にどう計算するかを指定できます。DefaultExpression は，項目値を参照しない有効な SQL 値式ならどんな式にもできます。式に数値以外のリテラルが含まれる場合は，引用符で囲まなければなりません。たとえば，時間項目の正午のデフォルト値は，リテラル値を引用符で囲んで次のようにします。

'12:00:00'


Working with constraints
Working with constraints1093031

Section topics 	参照

Delphi では，項目コンポーネントは SQL サーバー制約を使えます。その上，アプリケーションではそのアプリケーションにローカルのカスタム制約を作成して使うこともできます。すべての制約は，項目が格納できる値のスコープまたは範囲に制限を課す条件または規則です。以降の各節では，項目コンポーネントレベルでの制約の操作について説明します。


Creating a custom constraint
Creating a custom constraint1093032

Section topics 	参照

カスタム制約はほかの制約のようにサーバーからインポートされる制約ではなく，ローカルアプリケーション内で宣言，実装，実施を行う制約です。そういうものとして，カスタム制約はデータ入力の事前検証の実施を提供することで役立ちますが，サーバーアプリケーションから受け取ったデータやサーバーアプリケーションへ設定されたデータに対してはカスタム制約を適用できません。

カスタム制約を作成する手順は次のとおりです。

1.	制約条件を指定する CustomConstraint プロパティを設定します。

2.	ユーザーが実行時に制約違反を起こした場合に表示するメッセージを ConstraintErrorMessage に設定します。

CustomConstraint は，項目の値に課されるアプリケーション固有の制約を指定する SQL 文字列です。ユーザーが項目に入力できる値を制限するように CustomConstraint を設定します。CustomConstraint は，有効であれば次のように，SQL 節にすることもできます。

x > 0 and x < 100

項目の値を参照するのに使われる名前は，制約式を通して一貫して使われる限り，予約済みの SQL キーワードでない文字列ならどんな文字列にもできます。

カスタム制約は項目値に対して課されるサーバーからの制約以外の制約です。サーバーが課す制約を確認するには，ImportedConstraint プロパティを見ます。


Using server constraints
Using server constraints1093033

Section topics 	参照

実際の SQL データベースはほとんどが制約を使って項目の可能な値に条件を課します。たとえば，項目で NULL 値を許容しなかったり，項目値がその列でユニークでなければならなかったり，あるいは項目値が 0 より大きく 150 未満でなければならなかったりします。Delphi アプリケーションではこのような条件を複製できますが，Delphi では ImportedConstraint プロパティの提供によってサーバーの制約をローカルに伝えます。

ImportedConstraint プロパティには，項目値を何らかの方法で制限する SQL 節を指定します。たとえば次のようにします。

Value > 0 and Value < 100

コメントとしてインポートされた標準外の SQL またはサーバー固有の SQL を，データベースエンジンでは解釈できないので編集する場合を除き，ImportedConstraint の値を変更しないでください。

項目値にほかにも制約を追加するには，CustomConstraint を使います。カスタム制約はインポートされた制約以外に課される制約です。サーバー制約が変化した場合，ImportedConstraint の値も変化しますが，CustomConstraint プロパティに導入された制約は持続します。

ImportedConstraint プロパティから制約を削除した場合，その制約に違反する項目値の妥当性が変わることはありません。制約を削除した結果，その制約はローカルにではなくサーバーによって検査されるようになります。制約をローカルに検査した場合は，違反が見つかったときに表示されるのは ConstraintErrorMessage プロパティで与えたエラーメッセージであって，サーバーからのエラーメッセージではありません。


See also1093034

TField

TStringField

TIntegerField

TSmallIntField

TWordField

TFloatField

TAutoIncField

TCurrencyField

TBCDField

TBooleanField

TDateTimeField

TDateField

TTimeField

TBlobField

TBytesField

TVarBytesField

TMemoField

TGraphicField


Working with tables
Working with tables1094001

Section topics 	参照

この章では，データベースアプリケーションでの TTable データセットコンポーネントの使い方について説明します。テーブルコンポーネントは，基礎になるデータセットテーブルの完全な構造とデータをカプセル化しています。テーブルコンポーネントは，その基本プロパティとメソッドの多くを TDataSet，TBDEDataSet，および TDBDataSet から継承します。したがって，この章で説明するテーブルコンポーネントに特有のプロパティやメソッドについて読む前に，「データセットについて」でデータセットの一般説明を，および「BDE 対応データセットについて」でデータセットの BDE 特有の説明を知っておく必要があります。


Using table components
Using table components1094002

Section topics 	参照

テーブルコンポーネントを使うと，Paradox，dBASE， Access，ODBC 準拠のデータベース，リモートサーバー上の SQL データベース（InterBase，Sybase，SQL Server など）のいずれのデータベースからも，その基礎となるデータベーステーブルの行や列にアクセスできます。

テーブルのどの行や列のデータも表示や変更ができ，またテーブルを行単位で操作できます。さらにレコードにフィルタをかけ，指定したフィルタ条件に基づいてテーブル中のすべてのレコードから一部分だけを取り出すこともできます。レコードを検索したり，テーブル全体をコピーまたは削除したり，テーブル間のマスター／リンク関係を作成したりできます。

メモ	テーブルコンポーネントは常に 1 つのデータベーステーブルを参照します。1 つのコンポーネントで複数のテーブルにアクセスする場合や，1 つ以上のテーブルの行と列の一部にだけアクセスする場合は，テーブルコンポーネントのかわりに問い合わせコンポーネントを使わなければなりません。問い合わせコンポーネントについての詳細は，「問い合わせの操作」を参照してください。


Setting up a table component
Setting up a table component1094003

Section topics 	参照

設計時にテーブルコンポーネントを設定する一般的な手順を次に示します。アプリケーションの要件に合わせてテーブルのプロパティを変更するときは，手順の追加が必要になることがあります。テーブルコンポーネントを作成する手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページにある Table コンポーネントをデータモジュールまたはフォームに入れ，その Name プロパティをアプリケーションに適したユニークな値に設定します。

2.	Table コンポーネントの DatabaseName プロパティをアクセス対象のデータベースの名前に設定します。

3.	TableName プロパティをデータベースのテーブル名に設定します。DatabaseName プロパティがすでに指定されている場合は，ドロップダウンリストからテーブルを選択できます。

4.	データソースコンポーネントをデータモジュールまたはフォームに入れ，その DataSet プロパティをテーブルコンポーネントの名前に設定します。データセットコンポーネントは，表示用にテーブルからデータベース対応コンポーネントに結果セットを渡すのに使います。

テーブルコンポーネントによってカプセル化されたデータにアクセスする手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページからデータソースコンポーネントを選択して，データモジュールまたはフォームに配置します。その DataSet プロパティをテーブルコンポーネント名に設定します。

2.	TDBGrid などのデータベース対応コントロールをフォームに入れ，そのコントロールの DataSource プロパティを，直前の手順で配置したデータソースコンポーネントの名前に設定します。

3.	テーブルコンポーネントの Active プロパティを True に設定します。


Specifying a database location
Specifying a database location1094004

Section topics 	参照

DatabaseName プロパティは Delphi がデータベーステーブルを探す場所を指定します。Paradox と Dbase の場合，DatabaseName に指定できるのは，BDE エリアス，または明示的なディレクトリパスになります。SQL テーブルの場合は，BDE エリアスを使わなければなりません。

BDE エリアスを指定するメリットは，コンテキストメニューから BDE 管理ツールを呼び出して，SQL エクスプローラでエリアス定義を変更するだけで，アプリケーション全体のデータソースを変更できる点にあります。BDE エリアスの使い方についての詳細は，SQL エクスプローラのオンラインヘルプを参照してください。

DatabaseName プロパティを設定する手順は次のとおりです。

1.	テーブルの Active プロパティを False に設定します。

2.	BDE エリアスまたはディレクトリパスを DatabaseName プロパティに指定します。

参考	アプリケーションでデータベースコンポーネントを使ってデータベーストランザクションを制御する場合，DatabaseName はデータベースコンポーネントの DatabaseName プロパティに定義されているローカルエリアスを設定できます。データベースコンポーネントについての詳細は，「データベースへの接続」を参照してください。


Specifying a table name
Specifying a table name1094005

Section topics 	参照

TableName プロパティはテーブルコンポーネントを使ってアクセスするデータベーステーブルを指定します。テーブルを指定する手順は次のとおりです。

1.	テーブルの Active プロパティを False に設定します。

2.	BDE エリアスまたはディレクトリパスを DatabaseName プロパティに設定します。DatabaseName の設定についての詳細は，「データベース位置の指定」を参照してください。

3.	TableName プロパティをアクセス先のテーブルに設定します。設計時には，オブジェクトインスペクタで TableName プロパティのドロップダウンリストの有効なテーブル名から選択できます。実行時には，有効な名前をコードで指定しなければなりません。

有効なテーブル名を指定すると，テーブルコンポーネントの Active プロパティを True に設定してデータベースに接続し，テーブルを開いて，データの表示と編集ができます。

以下に示す方法で，テーブルコンポーネントに関連するテーブルを実行時に設定または変更できます。

Active を False に設定

有効なテーブル名を TableName プロパティに割り当てる

たとえば次のコードは，現在のテーブル名に基づいて OrderOrCustTable テーブルコンポーネントのテーブル名を変更します。

with OrderOrCustTable do

begin

  Active := False; { テーブルを閉じる }

  if TableName = 'CUSTOMER.DB' then

    TableName := 'ORDERS.DB'

  else

    TableName := 'CUSTOMER.DB';

  Active := True; { 新しいテーブルで再度開く }

end;


Specifying the table type for Paradox, dBASE, and ASCII tables
Specifying the table type for Paradox, dBASE, and ASCII tables1094006

Section topics 	参照

アプリケーションが Paradox テーブル，dBASE テーブル，カンマ区切り ASCII テキストテーブルにアクセスする場合，BDE は TableType プロパティを使ってテーブルの種類（想定される構造）を決めます。アプリケーションがデータベースサーバー上の SQL テーブルにアクセスするときは TableType を使いません。

デフォルトでは TableType は ttDefault に設定されます。TableType が ttDefault の場合，BDE はテーブルの種類をファイル名拡張子から決めます。表に，BDE が認識できるファイル名拡張子とそれに対応するテーブルの種類を示します。

拡張子	テーブルの種類
なし	Paradox
.DB	Paradox
.DBF	Dbase
.TXT	ASCII text
ローカルの Paradox テーブル，dBASE テーブル，ASCII テキストテーブルが表 10.1 のファイル名拡張子を使う場合，TableType を ttDefault のままにすることができます。これ以外のファイル名拡張子を使う場合，正しいテーブルの種類を示すように，アプリケーションで TableType を設定しなければなりません。表に TableType に設定できる値を示します。

値	テーブルの種類
ttDefault	BDE で自動的に判断されるテーブルの種類
ttParadox	Paradox
ttDBase	dBASE
ttASCII	カンマで区切られた ASCII テキスト


Opening and closing a table
Opening and closing a table1094007

Section topics 	参照

TDBGrid などのデータベース対応コントロールでテーブルのデータを表示して編集するには，テーブルを開きます。テーブルを開くには，Active プロパティを True に設定するか，Open メソッドを呼び出します。開いたテーブルは dsBrowse 状態になり，テーブルのデータソースに関連付けられたアクティブコントロールのデータが表示されます。

データの表示と編集を終了したり，テーブルコンポーネントの基本プロパティ（DatabaseName，TableName，TableType など）の値を変更するには，保留中のすべての変更を最初に登録または破棄します。キャッシュアップデートが有効な場合，ApplyUpdates メソッドを呼び出し，登録された変更をデータベースに書き込みます。最後にテーブルを閉じます。

テーブルを閉じるには，Active プロパティを False に設定するか，Close メソッドを呼び出します。閉じたテーブルは dsInactive 状態になります。テーブルのデータソースに関連付けられたアクティブコントロールはクリアされます。


Controlling read/write access to a table
Controlling read/write access to a table1094008

Section topics 	参照

デフォルトでは，テーブルを開いた場合，基礎になるデータベーステーブルの読み書き特権が要求されます。そのデータベーステーブルの特性に基づき，要求された書き込み特権が付与されないこともあります（リモートサーバー上の SQL テーブルに対して書き込みアクセスを要求したときに，テーブルのアクセスをサーバーが読み出しに制限している場合など）。

アプリケーションからテーブルへの読み書きアクセスに影響を与えるテーブルコンポーネントのプロパティは，CanModify，ReadOnly，Exclusive の 3 つです。

CanModify は読み出し専用プロパティで，基礎となるデータベーステーブルへの読み書きアクセスをテーブルコンポーネントに許可するかどうかを指定します。実行時にテーブルを開いた後では，アプリケーションでそのテーブルの CanModify を調べて，そのテーブルが書き込みアクセスを持っているかどうかをテストできます。CanModify が False の場合，そのアプリケーションはデータベースに書き込みができません。CanModify が True の場合，アプリケーションはテーブルの ReadOnly プロパティが False で提供されたデータベースに書き込みができます。

ReadOnly はデータの表示と編集をユーザーに許可するかどうかを指定します。ReadOnly が False（デフォルト）の場合，ユーザーはデータの表示と編集が両方ともできます。ユーザーがデータの表示だけしかできないようにするには，テーブルを開く前に ReadOnly を True に設定します。

Exclusive は，Paradox または dBASE のテーブルへの排他的な読み書きアクセスをアプリケーションに許可するかどうかを指定します。これらのテーブルに排他的に読み書きアクセスができるようにするには，テーブルを開く前にテーブルコンポーネントの Exclusive プロパティを True に設定します。排他的アクセスでテーブルを開くと，ほかのアプリケーションはそのテーブルでデータの読み書きができなくなります。排他的アクセス要求は，開こうとするテーブルが使用中のときは認められません。

次の文は排他的アクセスでテーブルを開きます。

CustomersTable.Exclusive := True; {排他的ロックの要求を設定する}

CustomersTable.Active := True; {ここでテーブルを開く}

メモ	SQL テーブルには Exclusive プロパティを設定できますが，サーバーによってはテーブルレベルの排他的ロックをサポートしていない場合があります。排他的ロックをサポートしていても，ほかのアプリケーションが SQL テーブルからデータを読み出すのを許可している場合があります。サーバーでのデータベーステーブルの排他的ロックについての詳細は，サーバーのマニュアルを参照してください。


Searching for records
Searching for records1094009

Section topics 	参照

Delphi には，テーブルから特定のレコードを検索するための方法がいくつか用意されています。汎用検索メソッドの Locate と Lookup を使う方法がもっとも柔軟性があり優れています。これらのメソッドは，インデックスやキーが付いているかどうかに関係なく，どんなテーブルのどんな種類の項目も検索できます。

Locate は指定された検索条件に一致する最初の行を見つけ，その行にカーソルを移動する

Lookup は指定された検索条件に一致する最初の行の値を返す（カーソルはその行に移動しない）

Locate や Lookup を使うときは，TTable だけでなく，どんな種類のデータセットも指定できます。Locate と Lookup についての詳細は，「データセットについて」を参照してください。

また前バージョンの Delphi との互換性のために，テーブルコンポーネントは Goto メソッドと Find メソッドを引き続きサポートしています。この 2 つのメソッドはこれまでのアプリケーションでの操作を可能にするためにここに示したものの，新しいアプリケーションでは必ず Locate と Lookup  を使ってください。さらに，既存のアプリケーションを新しいメソッドを使うように書きかえることで処理効率が向上する可能性があります。


Searching for records based on indexed fields
Searching for records based on indexed fields1094010

Section topics 	参照

テーブルコンポーネントは下位互換性のために Goto... 検索メソッドをサポートしています。Goto... メソッドを使うと，キーと呼ばれるインデックス付き項目を基準にしてレコードを検索し，見つかった最初のレコードを現在のレコードにできます。

Paradox テーブルと dBASE テーブルでは，インデックス項目だけを検索できます。このインデックスはテーブルコンポーネントの IndexName プロパティで指定できます。SQL テーブルでは，IndexFieldNames プロパティに指定する項目のリストをキーにすることもできます。Paradox テーブルまたは dBASE テーブルに項目リストを指定することもできますが，すべての項目にインデックスを定義しなければなりません。IndexName と IndexFieldNames についての詳細は，「代替インデックスで検索する」を参照してください。

参考	Paradox テーブルまたは dBASE テーブルをインデックスの付いていない項目で検索するには，Locate を使うか，TQuery コンポーネントと SELECT 文を使います。TQuery コンポーネントについての詳細は，「問い合わせの操作」を参照してください。

表に，レコードの検索に使える 6 つの Goto... メソッドと Find... メソッドについて要約します。

メソッド	用途
EditKey	検索キーバッファの現在の内容を保持してテーブルを dsSetKey 状態にし，検索の実行前にアプリケーションで既存の検索条件を変更できるようにする
FindKey	SetKey メソッドと GotoKey メソッドを 1 つのメソッドにまとめたもの
FindNearest	SetKey メソッドと GotoNearest メソッドを 1 つのメソッドにまとめたもの
GotoKey	検索条件と完全に一致する最初のレコードをデータセット内から検索して，見つかったレコードにカーソルを移動する
GotoNearest	部分キー値に基づき，値がもっとも近いレコードを文字列ベース項目で検索して，カーソルをそのレコードに移動する
SetKey	検索キーバッファをクリアしてテーブルを dsSetKey 状態にし，検索の実行前にアプリケーションで新しい検索条件を指定できるようにする
GotoKey と FindKey は論理関数で，検索に成功すると一致したレコードにカーソルを移動して True を返します。検索に失敗すると，カーソルを移動せずに False を返します。

GotoNearest と FindNearest は，完全に一致した最初のレコードにカーソルを移動します。一致したレコードが見つからないときは，指定された検索条件よりも大きい値の最初のレコードに移動します。

Executing a search with Goto methods1094011

Goto... メソッドを使って検索を実行する手順は次のとおりです。

1.	必要であれば，検索に使うインデックスを IndexName プロパティに指定します（SQL テーブルの場合は，キーとして使う項目のリストを IndexFieldNames に指定します）。テーブルの一次インデックスを使う場合は，これらのプロパティを設定する必要はありません。

2.	テーブルを開きます。

3.	SetKey でテーブルを dsSetKey 状態にします。

4.	検索値を Fields プロパティに指定します。Fields は，列に対応する順序番号でインデックスを付けた文字列リストです。テーブルの最初の列番号は 0 です。

5.	GotoKey または GotoNearest で検索して，一致した最初のレコードに移動します。

たとえば，ボタンの OnClick イベントに結び付けられた次のコードは，フォーム上の編集ボックスの文字と完全に一致する項目値を含む最初のレコードに移動する例です。

procedure TSearchDemo.SearchExactClick(Sender: TObject);

begin

  Table1.SetKey;

  Table1.Fields[0].AsString := Edit1.Text;

  if not Table1.GotoKey then

    ShowMessage('Record not found');

end;

GotoNearest も似ています。GotoNearest は部分項目値にもっとも近いレコードを検索します。これは文字列項目にだけ使えます。次に例を示します。

Table1.SetKey;

Table1.Fields[0].AsString := 'Sm';

Table1.GotoNearest;

最初の 2 文字が「Sm」であるレコードが存在する場合，カーソルがそのレコードに移動します。見つからない場合，カーソルの位置は変わらず，GotoNearest は False を返します。

Executing a search with Find methods1094012

Find... メソッドを使って検索を実行する手順は次のとおりです。

1.	必要であれば，検索に使うインデックスを IndexName プロパティに指定します（SQL テーブルの場合は，キーとして使う項目のリストを IndexFieldNames に指定します）。テーブルの一次インデックスを使う場合は，これらのプロパティを設定する必要はありません。

2.	テーブルを開きます。

3.	FindKey または FindNearest で検索して，一致した最初のレコードまたは値がもっとも近いレコードに移動します。どちらのメソッドも，カンマで区切られた項目値のリストをパラメータとして取ります。各項目値は，基礎となるテーブル内のインデックスの付いた列に対応しています。

メモ	FindNearest は文字列項目にだけ使えます。


Specifying the current record after a successful search
Specifying the current record after a successful search1094013

Section topics 	参照

デフォルトでは検索に成功すると，検索条件に一致する最初のレコードにカーソルが移動します。テーブルコンポーネントの KeyExclusive プロパティを True に設定すれば，一致する最初のレコードの次のレコードにカーソルを移動できます。

KeyExclusive のデフォルトは False で，検索が成功すると，カーソルは一致した最初のレコードに移動します。


Searching on partial keys
Searching on partial keys1094014

Section topics 	参照

テーブルに 2 つ以上のキー列がある場合，そのキーの一部だけから値を検索したければ，KeyFieldCount を検索対象の列数に設定します。たとえば，テーブルに 3 列の一次キーがあり，最初の列だけで値を検索したい場合は，KeyFieldCount を 1 に設定します。

複数列のキーを持つテーブルの場合，値の検索は第 1 列目から始まる連続した列でだけできます。たとえば 3 列キーの場合は，最初の列，最初の列と 2 番目の列，最初の列と 2 番目の列と 3 番目の列の組で値の検索はできますが，最初の列と 3 番目の列という組み合わせでは検索できません。


Searching on alternate indexes
Searching on alternate indexes1094015

Section topics 	参照

テーブルの一次インデックス以外のインデックスで検索したい場合は，使うインデックスの名前をそのテーブルの IndexName プロパティに指定しなければなりません。IndexName に値を指定する場合，テーブルは閉じていなければなりません。たとえば，CUSTOMER テーブルに「CityIndex」という二次インデックスがあり，そのインデックスで値を検索したい場合は，そのテーブルの IndexName プロパティの値を「CityIndex」に設定する必要があります。

Table1.Close;

Table1.IndexName := 'CityIndex';

Table1.Open;

Table1.SetKey;

Table1['City'] := Edit1.Text;

Table1.GotoNearest;

インデックス名を指定するかわりに，キーとして使う項目のリストを IndexFieldNames プロパティに指定できます。Paradox テーブルと dBASE テーブルの場合，指定する項目にはインデックスが付いていなければならず，インデックスが付いていないと検索の実行時に例外が生成されます。SQL テーブルの場合，指定する項目にはインデックスが付いている必要がありません。


Repeating or extending a search
Repeating or extending a search1094016

Section topics 	参照

SetKey や FindKey を呼び出すたびに，Fields プロパティの前回の値はクリアされます。前回の設定項目を使って検索を繰り返したい場合や，検索で使われた項目に追加したい場合は，SetKey や FindKey のかわりに EditKey を呼び出します。たとえば，上の検索を拡張して指定の国の指定された都市名のレコードを見つけるには，次のコードを使います。

Table1.EditKey;

Table1['Country'] := Edit2.Text;

Table1.GotoNearest;


Sorting records
Sorting records1094017

Section topics 	参照

インデックスはテーブルのレコードの表示順を決めます。一般に Delphi では，レコードは一次キーに基づいて昇順で表示されます（一次インデックスのない dBASE テーブルの場合，ソート順は物理的なレコードの順序に基づきます）。このデフォルトの動作には，アプリケーションの介入は必要ありません。ただし，別のソート順を希望する場合は，以下の指定が必要です。

代替インデックス

ソートの基準列のリスト（SQL のみ）

異なるソート順を指定する手順は次のとおりです。

1.	使用可能なインデックスを調べます。

2.	使う代替インデックスまたは列のリストを指定します。


Retrieving a list of available indexes with GetIndexNames
Retrieving a list of available indexes with GetIndexNames1094018

Section topics 	参照

実行時にアプリケーションで GetIndexNames メソッドを呼び出して，テーブルの利用可能なインデックスのリストを取り出せます。GetIndexNames は有効なインデックス名を含む文字列リストを返します。たとえば次のコードは，CustomersTable データセットで利用可能なインデックスのリストを決めます。

var

  IndexList: TList;

...

CustomersTable.GetIndexNames(IndexList);

メモ	Paradox テーブルの場合，一次インデックスに名前は付かないので，GetIndexNames では一次インデックスは返されません。代替インデックスを使った後で，Paradox テーブルで一次キーを使うように戻すには，そのテーブルの IndexName プロパティをヌル文字列に設定してください。


Specifying an alternative index with IndexName
Specifying an alternative index with IndexName1094019

Section topics 	参照

代替インデックスでテーブルをソートするように指定するには，そのテーブルコンポーネントの IndexName プロパティにインデックス名を指定します。設計時には，この名前をオブジェクトインスペクタで指定でき，実行時には，コードで IndexName プロパティにアクセスできます。たとえば次のコードは，CustomersTable のインデックスを CustDescending に設定します。

CustomersTable.IndexName := 'CustDescending';

Specifying a dBASE index file1094020

プロダクションファイル以外のインデックスファイルを使う dBASE テーブルの場合，IndexName プロパティを設定する前に，IndexFiles プロパティを使用対象インデックスファイルの名前に設定します。設計時にオブジェクトインスペクタで IndexFiles プロパティの値列にある省略記号ボタンをクリックすれば，インデックスファイルエディタを呼び出せます。

利用可能なインデックスファイルのリストを表示するには，［追加(A)］を選択します。表示されるリストから 1 つまたは複数のインデックスファイルを選択します。dBASE インデックスファイルには複数のインデックスを入れられます。インデックスファイルからインデックスを選択するには，オブジェクトインスペクタで IndexName ドロップダウンリストからインデックス名を選択します。各インデックス名をセミコロンで区切って入力し，ファイルに複数のインデックスを指定することもできます。

実行時に IndexFiles と IndexName を設定することもできます。たとえば次のコードは，AnimalsTable テーブルコンポーネントの IndexFiles を ANIMALS.MDX に設定し，IndexName を NAME に設定します。

AnimalsTable.IndexFiles := 'ANIMALS.MDX';

AnimalsTable.IndexName := 'NAME';


Specifying sort order for SQL tables
Specifying sort order for SQL tables1094021

Section topics 	参照

SQL では，行のソート順は ORDER BY 節で決まります。この節で使われるインデックスは以下のどちらかで指定できます。

既存のインデックスを指定する IndexName プロパティ

テーブルの一部の列に基づき疑似インデックスを作成する IndexFieldNames プロパティ

IndexName と IndexFieldNames は同時には使えないプロパティです。一方のプロパティを設定すると，もう一方のプロパティの値がクリアされます。IndexName を使うには，「代替インデックスで検索する」を参照してください。

Specifying fields with IndexFieldNames1094022

IndexFieldNames は文字列リストプロパティです。ソート順を指定するには，使われる順に各列名をセミコロンで区切って指定します。ソートは昇順によるものだけです。ソートの大文字と小文字を区別するかどうかは，サーバーの機能によって決まります。詳細はサーバーのマニュアルを参照してください。

次のコードは PhoneTable のソート順を LastName に基づいて設定し，続いて FirstName に基づいて設定します。

PhoneTable.IndexFieldNames := 'LastName;FirstName';

メモ	Paradox や dBASE のテーブルで IndexFieldNames を使う場合，Delphi は指定された列を使うインデックスを見つけようと試みます。そのようなインデックスを見つけられない場合は，例外を生成します。


Examining the field list for an index
Examining the field list for an index1094023

Section topics 	参照

アプリケーションで実行時にインデックスを使う場合，以下の 2 つのプロパティを調べることができます。

インデックスの列数を決める IndexFieldCount プロパティ

インデックスを構成する列名のリストを調べる IndexFields プロパティ

IndexFields はインデックスの列名を含んだ文字列リストです。次のコードは，IndexFieldCount プロパティと IndexFields プロパティを使ってアプリケーション内で列名リストを繰り返し処理する方法を示しています。

var

  I: Integer;

  ListOfIndexFields: array[0 to 20} of string;

begin

with CustomersTable do

  begin

  for I := 0 to IndexFieldCount - 1 do

     ListOfIndexFields[I] := IndexFields[I];

  end;

end;

メモ	IndexFieldCount は式インデックスで開いている dBASE テーブルでは無効です。


Working with a subset of data
Working with a subset of data1094024

Section topics 	参照

実際のテーブルは非常に大きくなる可能性があるため，通常アプリケーションでは操作対象の行の数を制限する必要があります。テーブルコンポーネントの場合，アプリケーションが使うレコードを制限する方法には範囲とフィルタの 2 通りがあります。フィルタは，TTable，TQuery，TStoredProc の各コンポーネントなど，どんな種類のデータセットにも使うことができます。フィルタの使い方についての詳細は，「データセットについて」を参照してください。

範囲は TTable コンポーネントにだけ使えます。フィルタと範囲は似ている点もありますが，データの選択方法が異なります。次の節では，フィルタと範囲の違いを示した後，範囲の使い方を説明します。


Understanding the differences between ranges and filters
Understanding the differences between ranges and filters1094025

Section topics 	参照

範囲もフィルタもテーブルの表示レコードとして一部のレコードだけを選択する点では同じですが，その方法が異なります。範囲では，指定した 2 つの境界値の間にある連続したインデックス付きレコードが取り出されます。たとえば，名字にインデックスが付いた社員データベースで，名字が「Jones」より大きく「Smith」より小さいすべての社員を表示するのに範囲を適用できます。範囲はインデックスに依存しているため，適用できるのはインデックスの付いた Paradox テーブルと dBASE テーブルだけです（SQL テーブルでは，IndexFieldNames プロパティに指定したどの項目にでも範囲を適用できます）。範囲は既存のインデックスでだけ並べ替えることができます。

フィルタでは，レコードにインデックスが付いているかどうかに関係なく，指定した条件を満たす連続または非連続のレコードが取り出されます。たとえば，社員データベースにフィルタを使うと，カリフォルニア在住で勤続 5 年以上のすべての社員を表示できます。フィルタは，インデックスが付いていればそれを使いますが，インデックスには依存しません。アプリケーションがデータセット内をスクロールするときに，フィルタがレコードごとに適用されます。

一般に，範囲よりフィルタの方が柔軟な使い方ができます。しかし，データセットが大きくて，アプリケーションが必要とするレコードが，連続したインデックス付きグループにブロックされている場合は，範囲を使うとよいでしょう。非常に大きなデータセットでは，表示や編集のために，問い合わせコンポーネントを使ってデータを選択するとさらに効果的です。フィルタの使い方についての詳細は，「データセットについて」を参照してください。問い合わせの使い方についての詳細は，「問い合わせの操作」を参照してください。


Creating and applying a new range
Creating and applying a new range1094026

Section topics 	参照

範囲を作成して適用する手順は次のとおりです。

1.	データセットを dsSetKey 状態にして，範囲の開始インデックス値を設定します。

2.	範囲の終了インデックス値を設定します。

3.	データセットに範囲を適用します。

Setting the beginning of a range1094027

SetRangeStart 手続きを呼び出してデータセットを dsSetKey 状態にし，範囲の開始値のリストを作成します。SetRangeStart を呼び出すと，それ以降に Fields プロパティに代入された値は，範囲の適用時に使われる開始インデックス値であるとみなされます。指定した項目は，Paradox と dBASE を使うときのインデックス付き項目でなければなりません。

たとえば，CUSTOMER テーブルにリンクした Customers データセットの各項目に静的な項目コンポーネントを作成した場合を考えます。CUSTOMER はその最初の列（CustNo）にインデックスが付いています。アプリケーションのフォームには StartVal と EndVal という 2 つの編集コンポーネントがあり，範囲の開始値と終了値を指定するのに使っているとします。その場合，次のコードを使って範囲を作成して適用できます。

with Customers do

begin

  SetRangeStart;

  FieldByName('CustNo') := StartVal.Text;

  SetRangeEnd;

  if EndVal.Text <> '' then

    FieldByName('CustNo') := EndVal.Text;

  ApplyRange;

end

このコードは項目に値を代入する前に，EndVal に入力されたテキストがヌルでないことを調べます。StartVal に入力されたテキストがヌルの場合，すべての値がヌルよりも大きいため，テーブルの先頭からすべてのレコードが含まれます。ただし，EndVal に入力されたテキストがヌルの場合，ヌルよりも小さいものはないため，レコードはどれも含まれなくなります。

複数列インデックスでは，インデックスのすべてまたは一部の項目に開始値を指定できます。インデックスで使われている項目に値を指定しないときは，範囲の適用時にヌル値が設定されます。インデックスの項目数よりも多くの値を設定すると，範囲の計算時に余分な項目が無視されます。

範囲の開始の指定を終了するには，SetRangeEnd または ApplyRange を呼び出します。これらのメソッドについては，以降の各節を参照してください。

参考	データセットの先頭で範囲を開始するには，SetRangeStart の呼び出しを省略します。

SetRange 手続きを呼び出して，範囲の開始値（および終了値）を設定することもできます。SetRange についての詳細は，「範囲の開始値と終了値の設定」を参照してください。

Setting the end of a range1094028

SetRangeEnd 手続きを呼び出してデータセットを dsSetKey 状態にし，範囲の終了値のリストを作成します。SetRangeEnd を呼び出すと，それ以降に Fields プロパティに代入された値は，範囲の適用時に使われる終了インデックス値であるとみなされます。指定した項目は，Paradox と dBASE を使うときのインデックス付き項目でなければなりません。

メモ	データセットの最後のレコードで範囲を終わらせる場合でも，範囲の終了値は必ず指定してください。範囲の終了値を指定しないと，ヌル値であるとみなされます。終了値がヌルの範囲は常に空です。

FieldByName メソッドを使うと，終了値を簡単に代入できます。次に例を示します。

with Table1 do

begin

  SetRangeStart;

  FieldByName('LastName') := Edit1.Text;

  SetRangeEnd;

  FieldByName('LastName') := Edit2.Text;

  ApplyRange;

end;

複数列インデックスでは，インデックスのすべてまたは一部の項目に終了値を指定できます。インデックスで使われている項目に値を指定しないときは，範囲の適用時にヌル値が設定されます。インデックスの項目数よりも多くの値を設定すると，例外が生成されます。

範囲の終了の指定を終了するには，ApplyRange を呼び出します。範囲の適用についての詳細は，「範囲の適用」を参照してください。

メモ	SetRange 手続きを呼び出して，範囲の終了値（および開始値）を設定することもできます。SetRange についての詳細は，「範囲の開始値と終了値の設定」を参照してください。

Setting start- and end-range values1094029

SetRangeStart と SetRangeEnd を別々に呼び出して範囲境界を設定するかわりに，SetRange 手続きを呼び出してデータセットを dsSetKey 状態にすれば，範囲の開始値と終了値を一度に設定できます。

SetRange は開始値群と終了値群の 2 つの定数配列パラメータを取ります。たとえば，次の文は 2 列インデックスに基づいて範囲を設定しています。

 SetRange([Edit1.Text, Edit2.Text], [Edit3.Text, Edit4.Text]);

複数列インデックスでは，インデックスのすべてまたは一部の項目に開始値と終了値を指定できます。インデックスで使われている項目に値を指定しないときは，範囲の適用時にヌル値が設定されます。インデックスの最初の項目の値を省略し，それ以外の項目に値を指定するには，省略する項目に nil または空の値を渡します。インデックスの項目数よりも多くの値を設定すると，範囲の計算時に余分な項目が無視されます。

メモ	データセットの最後のレコードで範囲を終わらせる場合でも，範囲の終了値は必ず指定してください。範囲の終了値を指定しないと，ヌル値であるとみなされます。終了値がヌルの範囲は，開始範囲値が終了範囲値以上になるため常に空です。

Specifying a range based on partial keys1094030

キーが 1 つまたは複数の文字列項目で構成されている場合，SetRange メソッド群は部分キーをサポートします。たとえば，LastName 列と FirstName 列に基づくインデックスがある場合，次の範囲指定は有効です。

Table1.SetRangeStart;

Table1['LastName'] := 'Smith';

Table1.SetRangeEnd;

Table1['LastName'] := 'Zzzzzz';

Table1.ApplyRange;

このコードは，LastName が「Smith」以上であるすべてのレコードを範囲に含みます。値の指定は次のようにもできます。

Table1['LastName'] := 'Sm';

この文は，LastName が「Sm」以上であるレコードを含みます。次の文は，LastName が「Smith」以上で FirstName が「J」以上であるレコードを含みます。

Table1['LastName'] := 'Smith';

Table1['FirstName'] := 'J';

Including or excluding records that match boundary values1094031

デフォルトでは，範囲には指定の開始値以上で指定の終了値以下のすべてのレコードが含まれます。KeyExclusive プロパティを使えば，開始値と終了値の境界に等しいレコードが含まれるかどうかを指定できます。デフォルトでは KeyExclusive は False です。

テーブルコンポーネントの KeyExclusive プロパティを True に設定すれば，指定の範囲の開始と終了の境界に等しいレコードを除外できます。

KeyExclusive := True;

Table1.SetRangeStart;

Table1['LastName'] := 'Smith';

Table1.SetRangeEnd;

Table1['LastName'] := 'Tyler';

Table1.ApplyRange;

このコードは，LastName が「Smith」より大きく「Tyler」より小さいすべてのレコードを範囲に含みます。

Applying a range1094032

前の節に示した SetRange メソッドは範囲の境界条件を設定しますが，これだけでは範囲は有効になりません。範囲を有効にするには ApplyRange 手続きを呼び出します。ApplyRange は，データセットの指定部分のデータに対し，ユーザーによる表示とアクセスをただちに制限します。

Canceling a range1094033

CancelRange メソッドは，範囲の適用を終了し，データセット全体にアクセスできるよう復元します。範囲を取り消したことによってデータセットのすべてのレコードへのアクセスが復元されても，後でその範囲をもう一度適用できるように，範囲の境界条件はそのまま使えます。新しい範囲境界を指定するか既存の境界を変更するまで，範囲境界は保存されます。たとえば，次のコードは有効です。

...

Table1.CancelRange;

...

{後で同じ範囲をもう一度使う。SetRangeStart などを呼び出す必要はない}

Table1.ApplyRange;

...


Modifying a range
Modifying a range1094034

Section topics 	参照

Delphi には，範囲の既存の境界条件を変更するための機能が 2 つあります。EditRangeStart は範囲の開始値を変更し，EditRangeEnd は範囲の終了値を変更します。

範囲の変更と適用を行う手順は次のとおりです。

1.	データセットを dsSetKey 状態にし，範囲の開始インデックス値を変更します。

2.	範囲の終了インデックス値を変更します。

3.	範囲をデータセットに適用します。

範囲の開始値と終了値のどちらかを変更することも，両方の境界条件を変更することもできます。データセットに現在適用されている範囲の境界条件を変更する場合，新たな変更が適用されるのは ApplyRange をもう一度呼び出したときです。

Editing the start of a range1094035

EditRangeStart 手続きを呼び出してデータセットを dsSetKey 状態にし，範囲の開始値の現在のリストを変更します。EditRangeStart を呼び出すと，それ以降に Fields プロパティに代入された値は，範囲の適用時に使われる現在のインデックス値を上書きします。指定した項目は，Paradox と dBASE を使うときのインデックス付き項目でなければなりません。

参考	部分キーに基づく開始範囲を最初に作成した場合，EditRangeStart を使って範囲の開始値を拡張できます。部分キーに基づく範囲についての詳細は，「部分キーに基づく範囲の指定」を参照してください。

Editing the end of a range1094036

EditRangeEnd 手続きを呼び出してデータセットを dsSetKey 状態にし，範囲の終了値の現在のリストを変更します。EditRangeEnd を呼び出すと，それ以降に Fields プロパティに代入された値は，範囲の適用時に使われる終了インデックス値であるとみなされます。指定した項目は，Paradox と dBASE を使うときのインデックス付き項目でなければなりません。

メモ	データセットの最後のレコードで範囲を終わらせる場合でも，範囲の終了値は必ず指定してください。範囲の終了値を指定しないと，ヌル値であるとみなされます。終了値がヌルの範囲は常に空です。


Deleting all records in a table
Deleting all records in a table1094037

Section topics 	参照

テーブルのすべてのデータ行を削除するには，テーブルコンポーネントの EmptyTable メソッドを実行時に呼び出します。SQL テーブルの場合，このメソッドが成功するのは，そのテーブルに対して DELETE 特権を持っている場合だけです。たとえば次の文は，データセットのすべてのレコードを削除します。

PhoneTable.EmptyTable;

注意	EmptyTable で削除したデータは元に戻せません。


Deleting a table
Deleting a table1094038

Section topics 	参照

データベースからテーブルを削除するには，テーブルコンポーネントの DeleteTable メソッドを呼び出します。たとえば次の文は，データセットの基礎になるテーブルを削除します。

CustomersTable.DeleteTable;

注意	DeleteTable でテーブルを削除した場合，テーブルとその中のすべてのデータは元に戻せません。


Creating a table
Creating a table1094039

Section topics 	参照

CreateTable メソッドを使うと，アプリケーションは実行時に新しいテーブルを作成できます。このメソッドを使うには，アプリケーションはテーブルコンポーネントを実行時にインスタンス化し，項目とインデックスの定義をテーブルに割り当てて，CreateTable を呼び出しで指定のテーブルを生成しなければなりません。CreateTable は SQL の知識がなくてもテーブルを作成できるように，プログラミングによる方法を提供します。ただし開発者は，Delphi データセットコンポーネント（特に TTable）に共通なプロパティ，イベント，メソッドについてよく知っている必要があります。

警告	既存のテーブルの名前と重複するテーブルを作成する場合，既存のテーブルとそのすべてのデータは新しく作成するテーブルで上書きされます。上書きされたテーブルとそのデータは回復できません。

CreateTable を使うためにアプリケーションが実行する手順は次のとおりです。

1.	テーブルコンポーネントの宣言とインスタンス化を行います。

2.	テーブルコンポーネントの DatabaseName プロパティと TableName プロパティを指定します。

3.	TableType プロパティを ttDefault または別の値に設定します。

4.	テーブルの既存の項目定義をすべてクリアします。

5.	FieldDefs プロパティに新しい項目定義を追加します。

6.	既存のインデックス定義をすべてクリアします。

7.	テーブルのインデックスオプションを指定します。

8.	必要であれば，1 つ以上のインデックスをテーブルに追加します。

9.	CreateTable を呼び出します。

たとえば，次のコードは新しいテーブルを作成し，それを DBDEMOS エリアスに関連付けます。新しいテーブルを作成する前に，指定されたテーブル名が既存のテーブル名と重複していないことを確認します。

var

  NewTable: TTable;

  NewIndexOptions: TIndexOptions;

  TableFound: Boolean;

begin

  NewTable := TTable.Create;

  NewIndexOptions := [ixPrimary, ixUnique];

  with NewTable do

  begin

    Active := False;

    DatabaseName := 'DBDEMOS';

    TableName := Edit1.Text;

    TableType := ttDefault;

    FieldDefs.Clear;

    FieldDefs.Add(Edit2.Text, ftInteger, 0, False);

    FieldDefs.Add(Edit3.Text, ftInteger, 0, False);

    IndexDefs.Clear;

    IndexDefs.Add('PrimaryIndex', Edit2.Text, NewIndexOptions);

  end;

  {このテーブルがすでに存在しているか調べる}

  TableFound := FindTable(Edit1.Text); {FindTable が示されないときのコード}

  if TableFound = True then

   if MessageDlg('Overwrite existing table ' + Edit1.Text + '?', mtConfirmation,

       mbYesNo, 0) = mrYes then

    TableFound := False;

  if not TableFound then

    CreateTable; {テーブルの作成}

  end;

end;


Importing data from another table
Importing data from another table1094040

Section topics 	参照

テーブルコンポーネントの BatchMove メソッドを使えば，別のテーブルからデータをインポートできます。BatchMove では以下のことができます。

別のテーブルから現在のテーブルにレコードをコピーする

別のテーブルと共通するレコードで現在のテーブルを更新する

別のテーブルのレコードを現在のテーブルの最後に追加する

別のテーブルと共通するレコードを現在のテーブルから削除する

BatchMove は 2 つのパラメータを取ります。1 つはデータのインポート元のテーブルの名前で，もう 1 つは実行するインポート操作を決めるモード指定です。表に，モード指定に使える設定を示します。

値	意味
batAppend	インポート元テーブルのすべてのレコードを現在のテーブルの最後に追加する
batAppendUpdate	インポート元テーブルのすべてのレコードを現在のテーブルの最後に追加し，現在のテーブルの既存のレコードをインポート元テーブルの同じレコードで更新する
batCopy	インポート元テーブルのすべてのレコードを現在のテーブルにコピーする
batDelete	インポート元テーブルと共通するすべてのレコードを現在のテーブルから削除する
batUpdate	現在のテーブルの既存のレコードをインポート元テーブルの対応するレコードで更新する
たとえば次のコードは，現在のテーブルのレコードを Customer テーブルのレコードで更新します。

Table1.BatchMove('CUSTOMER.DB', batUpdate);

BatchMove は正常にインポートできたレコードの数を返します。

注意	batCopy モードでレコードをインポートすると，既存のレコードが上書きされます。既存のレコードを保存するには batAppend を使います。

BatchMove は，TBatchMove コンポーネントを通じてアプリケーションが直接使える機能だけを実行します。テーブル内またはテーブル間で大量のデータを移動する必要があるときは，テーブルの BatchMove 関数を呼び出すのではなく，バッチ移動コンポーネントを使ってください。TBatchMove の使い方についての詳細は，「データ構造とテーブル構造のコピー」を参照してください。


Synchronizing tables linked to the same database table
Synchronizing tables linked to the same database table1094041

Section topics 	参照

複数のテーブルコンポーネントが DatabaseName プロパティと TableName プロパティによって同一のデータベーステーブルにリンクしており，各テーブルがデータソースコンポーネントを共有していない場合，各テーブルではデータに独自のビューと独自の現在のレコードをそれぞれ持ちます。ユーザーが各テーブルコンポーネントを使ってレコードにアクセスした場合，そのコンポーネントの現在のレコードはそれぞれ異なります。

これらのテーブルコンポーネントのそれぞれの現在のレコードは，GotoCurrent メソッドで強制的に同一にできます。GotoCurrent はそれ自身のテーブルの現在のレコードを，別のテーブルコンポーネントの現在のレコードと同じにします。たとえば次のコードは，CustomerTableOne の現在のレコードを CustomerTableTwo の現在のレコードと同じにします。

CustomerTableOne.GotoCurrent(CustomerTableTwo);

参考	アプリケーションでこのようなテーブルコンポーネントの同期が必要な場合は，それらのコンポーネントをデータモジュールに入れ，そのデータモジュールを，同期させるテーブルにアクセスする各フォームの uses 節に追加します。

別々のフォームにあるテーブルコンポーネントを同期させる必要がある場合は，一方のフォームをもう一方のフォームの uses 節に追加し，そのフォーム名とテーブル名を指定しなければなりません。次に例を示します。

CustomerTableOne.GotoCurrent(Form2.CustomerTableTwo);


Creating master/detail forms
Creating master/detail forms1094042

Section topics 	参照

テーブルコンポーネントの MasterSource プロパティと MasterFields プロパティを使うと，2 つのテーブル間に 1 対多の関係を確立できます。

MasterSource プロパティは，マスターテーブル用のデータの取得元であるデータソースを指定するために使います。たとえば，マスター／リンク関係で 2 つのテーブルをリンクした場合，マスターテーブルのデータソースコンポーネントをこのプロパティに指定することでリンクテーブルはマスターテーブルで発生するイベントを追跡できるようになります。

MasterFields プロパティは，リンクの確立に使われる両方のテーブルに共通する列を指定します。複数の列名に基づいてテーブルをリンクするには，各列名をセミコロンで区切った次のようなリストを使います。

Table1.MasterFields := 'OrderNo;ItemNo';

2 つのテーブル間のリンクを作成するには，リンク項目デザイナを使うと便利です。リンク項目デザイナについての詳細は，『ユーザーズガイド』を参照してください。


Building an example master/detail form
Building a sample master/detail form1094043

Section topics 	参照

ユーザーが顧客レコードをスクロールして現在の顧客の注文すべてを表示できる単純なフォームを作成する手順は次のとおりです。マスターテーブルは CustomersTable テーブルで，リンクテーブルは OrdersTable テーブルです。

1.	2 つの TTable コンポーネントと 2 つの TDataSource コンポーネントをデータモジュールに入れます。

2.	最初の TTable コンポーネントのプロパティを以下のように設定します。

DatabaseName は DBDEMOS

TableName は CUSTOMER.DB

Name は CustomersTable

3.	2 つ目の TTable コンポーネントのプロパティを以下のように設定します。

DatabaseName は DBDEMOS

TableName は ORDERS.DB

Name は OrdersTable

4.	最初の TDataSource コンポーネントのプロパティを以下のように設定します。

Name は CustomersSource

DataSet は CustomersTable

5.	2 つ目の TDataSource コンポーネントのプロパティを以下のように設定します。

Name は OrdersSource

DataSet は OrdersTable

6.	新しくフォームを作り 2 つの TDBGrid コンポーネントを入れます。

7.	［ファイル(F)｜ユニットを使う(U)］を選択して，そのフォームが手順の 1 で作ったデータモジュールを使うことを指定します。

8.	最初のグリッドコンポーネントの DataSource プロパティを「CustomersSource」に，2 つ目のグリッドコンポーネントの DataSource プロパティを「OrdersSource」に設定します。

9.	OrdersTable の MasterSource プロパティを「CustomersSource」に設定します。これで，CUSTOMER テーブル（マスターテーブルつまりコントロールテーブル）と ORDERS テーブル（リンクテーブル）がリンクされます。

10.	オブジェクトインスペクタで MasterFields プロパティの値列をダブルクリックしてリンク項目デザイナを呼び出し，以下のようにプロパティを設定します。

［選択可能なインデックス(V)］フィールドで［CustNo］を選択して，CustNo 項目で 2 つのテーブルをリンクする

［リンク項目(E)］と［マスター項目(M)］の両方の項目リストで［CustNo］を選択する

［追加(A)］ボタンをクリックしてこの結合条件を追加する。［統合した項目(J)］リストに「CustNo -> CustNo」と表示される

設定が終わったら［OK］を選択してリンク項目デザイナを終了します。

11.	CustomersTable と OrdersTable の Active プロパティを True に設定して，フォームのグリッドにデータを表示します。

12.	アプリケーションをコンパイルして実行します。

アプリケーションを実行すると，テーブルがリンクされます。CUSTOMER レコードを表示しているグリッドで新しいレコードに移動すると，ORDER レコードを表示するグリッドが現在の顧客に関連付けられたオーダーを表示するように変更されます。

アプリケーションを実行すると，2 つのテーブルがリンクしていることがわかるでしょう。CUSTOMER テーブルを表示しているグリッドは，CUSTOMER テーブルの現在位置のデータに関連付けられたレコードだけを表示します。


See also1094044

TTable

TDataSet

データセットについて

BDE 対応データセット


Working with queries
Working with queries1095001

Section topics 	参照

この章では，SQL 文を使ってデータにアクセスするのに必要な TQuery データセットコンポーネントについて説明します。ここでは，「データセットについて」のデータセットおよびデータソースについての一般説明を理解しているものと想定しています。

問い合わせコンポーネントは 1 つまたは複数のデータベーステーブルのデータの検索，挿入，更新，削除にクライアントアプリケーションで使われる SQL 文をカプセル化します。SQL は，リモートサーバーベースのほとんどのデータベース（Sybase，Oracle，InterBase，Microsoft SQL Server など）で使われている業界標準のリレーショナルデータベース言語です。Delphi の問い合わせコンポーネントは，リモートデータベースサーバー（Delphi Client/Server Suite のみ），Paradox，dBASE，FoxPro，Access，OBDC 準拠のデータベースと一緒に使えます。


Using queries effectively
Using queries effectively1095002

Section topics 	参照

問い合わせコンポーネントを効果的に使うには，以下のことを理解している必要があります。

SQL とサーバーの SQL 実装の詳細（SQL-92 標準に対する機能拡張や制約など）

ボーランドデータベースエンジン（BDE）

サーバーベースのアプリケーションに移行しようとしている熟練の「ローカルデータベース開発者」の場合は，「デスクトップ開発者向けの問い合わせの概要」を読んでください。SQL を扱うのが初めての場合は，SQL を詳細に解説した市販の解説書を参照してください。1 つお勧めできるのは，「Understanding the New SQL: A Complete Guide」，Jim Melton and Alan R. Simpson 著，Morgan Kaufmann Publishers です。

すでにデータベースサーバーの開発経験がありクライアントを Delphi で初めて構築しようとしている場合は，SQL とサーバーについてすでによく知っているはずです。さらに BDE に関する知識を付けなくてはなりません。BDE についてよく知らない場合は，「サーバー開発者向けの問い合わせの概要」を読んでください。


Queries for desktop developers
Queries for desktop developers1095003

Section topics 	参照

デスクトップの開発者は，Delphi と BDE が使う基本テーブル，レコード，項目のしくみにすでに慣れているはずです。TTable コンポーネントを使ってデータセット内の各データレコードの項目にアクセスすることはよくあります。テーブルの TableName プロパティを設定するときに，アクセスするデータベーステーブルを指定することもわかっています。

アプリケーションから参照するレコードに制限を与えるために，TTable の範囲プロパティやフィルタプロパティとそのメソッドを使ったこともあるでしょう。範囲を指定すると，指定した境界条件を満足する連続したインデックス付きレコード群へデータアクセスを一時的に取得できます（姓が「Jones」から「Smith」までのすべての従業員へのレコードを得たい場合などです）。フィルタを設定すると，フィルタ基準を満足する非連続のレコード群へのデータアクセス制限が行われます（California の住所を持つ顧客レコードだけを得たい場合などです）。

問い合わせはテーブルに対するフィルターと多くの点でよく似ています。問い合わせコンポーネントの SQL プロパティ（および Params プロパティ）を使うことで，データセットに対し直接，検索，挿入，削除，更新を行うことができる点でテーブルとは異なります。問い合わせでは以下のようなことができるため，ある面ではフィルタを使うよりも強力であるといえます。

一度に複数のテーブルにアクセスできる（SQL では「結合」と呼ばれる）

必ずすべての行と列を返すのではなく，基礎になるテーブルの行や列の一部にアクセスできる。これにより性能とセキュリティの両方が向上する。不要なデータにメモリが消費されることがなく，表示や変更してはならない項目へのアクセスを防ぐことができる

問い合わせはパラメータなしで使うこともパラメータ付きで使うこともできます。パラメータを使う問い合わせはパラメータ付きの問い合わせとも呼ばれます。パラメータ付きの問い合わせを使う場合，パラメータに現在代入されている実際の値を BDE が問い合わせに挿入してから，問い合わせを実行します。パラメータ付きの問い合わせは，実行時にユーザーのデータ表示やデータアクセスを変更できるのでたいへん柔軟性に富んでいます。

問い合わせは，テーブルコンポーネントを使うときと同様に，アプリケーションでユーザーに表示するデータを選択するのによく使います。しかし，問い合わせは表示するレコードの検索だけでなく，更新，挿入，削除もできます。問い合わせを使って挿入，更新，削除をする場合，問い合わせは表示するレコードを普通は返しません。この点で問い合わせはテーブルと異なります。

SQL プロパティを使って SQL 文を作成する方法については，「実行する SQL 文の指定」を参照してください。SQL 文のパラメータの使い方については，「パラメータの設定」を参照してください。問い合わせの実行方法については，「問い合わせの実行」を参照してください。


Queries for server developers
Queries for server developers1095004

Section topics 	参照

サーバー開発者は，SQL についてだけでなくデータベースサーバーの機能をすでに理解しているはずです。問い合わせとは，データのアクセスに使う SQL 文のことです。この文の使い方や扱い方，SQL 文にオプションのパラメータを指定して使う方法についてはすでに知っていることでしょう。

問い合わせコンポーネントでもっとも重要なのは SQL 文とそのパラメータです。問い合わせコンポーネントの SQL プロパティは，データアクセスに使う SQL 文を与えるのに使います。問い合わせコンポーネントの Params プロパティは，問い合わせに結合するパラメータのオプション配列です。ただし，Delphi の場合，問い合わせコンポーネントは単に SQL 文とそのパラメータにとどまっているわけではありません。クライアントアプリケーションと BDE のインターフェースの役割も果たします。

クライアントアプリケーションは，問い合わせコンポーネントのプロパティとメソッドを使って SQL 文とパラメータの操作，問い合わせるデータベースの指定，パラメータ付きの問い合わせの準備と準備解除，問い合わせの実行などを行います。問い合わせコンポーネントのメソッドは BDE を呼び出し，BDE は問い合わせ要求を処理し，SQL Link ドライバを通してデータベースサーバーと通信します。サーバーは必要であれば結果セットを BDE に返し，BDE はその結果セットを問い合わせコンポーネントを通してアプリケーションに返します。

問い合わせコンポーネントを操作する場合，BDE 機能を表す用語の中には SQL データベースプログラマとして使うときとまったく異なる意味を持つものがあるので最初はとまどうことがあります。たとえば，BDE ではデータベースサーバーへのパスの短縮名を「エリアス」と一般に呼んでいます。BDE エリアスは環境設定ファイルに格納されており，問い合わせコンポーネントの DatabaseNameプロパティに設定されます（ただし SQL 文では依然としてテーブルエリアスを使えます）。

メモ	ボーランド社が作成するマニュアルでは BDE 用語を使っているので，この章でも BDE 用語を使います。BDE 用語を使っているため意味が紛らわしい場合は説明を付けてあります。

SQL プロパティを使って SQL 文を作成する方法については，「実行する SQL 文の指定」を参照してください。SQL 文のパラメータの使い方については，「パラメータの設定」を参照してください。問い合わせの準備については，「問い合わせの準備」を参照してください。問い合わせの実行方法については，「問い合わせの実行」を参照してください。


What databases can you access with a query component?
What databases can you access with a query component?1095005

Section topics 	参照

TQuery コンポーネントは以下の中にあるデータにアクセスできます。

ローカル SQL（BDE の一部）を使う Paradox または dBASE テーブル。ローカル SQL は一部の DDL 構文を除いて SQL-92 標準をサポートする

InterBase エンジンを使うローカル InterBase サーバーデータベース。InterBase の SQL-92 標準の SQL 構文サポートと拡張構文サポートについては，『InterBase 言語リファレンス』を参照

Oracle，Sybase，MS-SQL Server，Informix，DB2，InterBase（Delphi Client/Server のみ）などのリモートデータベースサーバー上のデータベース。リモートサーバーにアクセスするには適切な SQL リンクをインストールしておく必要がある。これらのサーバーがサポートする標準の SQL 構文はどれも使うことができる。SQL の構文，制約，拡張機能については，サーバーのマニュアルを参照

Delphi は複数の種類のサーバーまたはテーブル（たとえば，Oracle テーブルのデータと Paradox テーブルのデータ）に対する異種間の問い合わせもできます。異種間の問い合わせを作成すると，BDE はローカル SQL を使って問い合わせを処理します。詳細については，「異種間の問い合わせの作成」を参照してください。


Using a query component: an overview
Using a query component: an overview1095006

Section topics 	参照

アプリケーションで問い合わせコンポーネントを使うために行う設計時の一般的な手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページにある問い合わせコンポーネントをデータモジュールに追加し，その Nameプロパティをアプリケーションに適したものに設定します。

2.	問い合わせコンポーネントの DatabaseName プロパティを問い合わせ対象のデータベースの名前に設定します。DatabaseName に指定できるのは BDE エリアスか，ローカルデータベースアクセスの場合なら明示的なディレクトリパスおよびデータベース名です。アプリケーションでデータベースコンポーネントを使う場合は，そのデータベースコンポーネントの DatabaseName プロパティで定義されているローカル BDE エリアスの名前を指定できます。

3.	問い合わせコンポーネントの SQL プロパティに SQL 文を指定します。必要であれば Params プロパティに SQL 文のパラメータを指定します。詳細については，「設計時の SQL プロパティの指定」を参照してください。

4.	コンポーネントパレットの［Data Access］ページにあるデータソースコンポーネントをデータモジュールに追加し，その DataSet プロパティを問い合わせコンポーネントの名前に設定します。データソースモジュールは問い合わせからデータベース対応コンポーネントに結果セット（問い合わせの結果）を返して表示するために使われます。

実行時に初めて問い合わせを実行するための一般的な手順は次のとおりです。

1.	問い合わせコンポーネントを閉じます。

2.	設計時に SQL プロパティを設定していない場合またはすでに指定した SQL 文を変更する場合は SQL プロパティに SQL 文を指定します。設計時の文をそのまま使う場合はこの手順を飛ばしてください。SQL プロパティの設定については，「実行する SQL 文の指定」を参照してください。

3.	直接または ParamByName メソッドを使って Params プロパティにパラメータとパラメータ値を設定します。問い合わせにパラメータが含まれていない場合または設計時に設定したパラメータを変更しない場合は，この手順をスキップしてください。パラメータの設定については，「パラメータの設定」を参照してください。

4.	Prepare を呼び出して BDE を初期設定し，パラメータ値を問い合わせに結合します。Prepare は必ずしも呼び出す必要はありませんが，できる限り呼び出してください。問い合わせの準備については，「問い合わせの準備」を参照してください。

5.	結果セットを返す問い合わせの場合は Open を呼び出し，結果セットを返さない問い合わせの場合は ExecSQL を呼び出します。問い合わせのオープンと実行については，「問い合わせの実行」を参照してください。

問い合わせを最初に 1 回実行したら，SQL 文を変更しない限りアプリケーションはそのつど準備をせずに問い合わせを何回でも閉じ，開き，実行できます。問い合わせの再利用については，「問い合わせの実行」を参照してください。


Specifying the SQL statement to execute
Specifying the SQL statement to execute1095007

Section topics 	参照

実行する SQL問い合わせ文を指定するには SQL プロパティを使います。問い合わせコンポーネントの Active プロパティを True に設定すると，設計時に問い合わせが自動的に準備され実行されます。実行時には Prepare を呼び出すと問い合わせが準備され，アプリケーションがコンポーネントの Open メソッドまたは ExecSQL メソッドを呼び出すと問い合わせが実行されます。

SQL プロパティは TString オブジェクトです。これは文字列の配列であり，これらを扱うプロパティ，イベント，メソッドの集合です。SQL内の文字列は自動的に連結されて，実行する SQL 文を生成します。SQL 文には文字列をいくつでも必要なだけ入れることができます。複数の文字列を使う利点は，SQL 文を論理単位に分割できることです（たとえば，SELECT 文の WHERE 節を独自の文字列に入れることができます）。これにより，問い合わせの変更やデバッグが容易になります。

SQL 文は，ハードコードの項目名と値を含む問い合わせの場合も，実行前に SQL 文に結合が必要な項目名や値を表す置換可能なパラメータが入っているパラメータ付きの問い合わせの場合もあります。たとえば，次の文は直に記述しています。

SELECT * FROM CUSTOMER WHERE CUSTNO = 1231

値を埋め込んだ問い合わせ文は，実行のたびに既知の一定の問い合わせを実行する場合に便利です。設計時または実行時には，必要であれば固定した問い合わせを別の固定した問い合わせまたはパラメータ付きの問い合わせに置換できます。SQL プロパティを変更すると，問い合わせはそのつど自動的に閉じて，準備解除されます。

メモ	問い合わせ内の列名にスペースまたは特殊文字が入っている場合は，列名を引用符で囲み，テーブル参照とピリオドを前に付ける必要があります（たとえば BIOLIFE.ﾓ名前ﾓ）。列の命名規則については，各サーバーのドキュメントを参照してください。

パラメータ付きの問い合わせには 1 つまたは複数のプレースホルダパラメータ，項目名の代わりのアプリケーション変数，比較値（SELECT 文の WHERE 節にあるものなど）を入れることができます。パラメータ付きの問い合わせを使うと，アプリケーションを書き直さずに値を変更できます。パラメータ値は初めて SQL 文を実行する前に SQL文に結合する必要があります。問い合わせを実行する前に明示的に Prepare メソッドを呼び出さないと Delphi が自動的に行います。

次の文はパラメータ付きの問い合わせの例です。

SELECT * FROM CUSTOMER WHERE CUSTNO = :Number

前にコロンが付く Number 変数は，実行時に与えられなければならない比較値を入れるパラメータで，文の実行ごとに変わる可能性があります。Number の実際の値は問い合わせコンポーネントの Params プロパティで与えられます。

参考	プログラミング時に，パラメータには列の実際の名前に対応した変数名を指定することを薦めます。たとえば，列名が「Number」ならば，対応したパラメータは「:Number」とします。対応する名前を使うと，問い合わせで DataSource プロパティを使ってパラメータ値を指定するときに，変数名を有効な項目名に対応付けることができ，プログラムがわかりやすくなります。


Specifying the SQL property at design time
Specifying the SQL property at design time1095008

Section topics 	参照

文字列リストエディタを使えば，設計時に SQL プロパティを指定できます。SQL プロパティの文字列リストエディタを呼び出すには，以下のどちらかの方法を実行します。

SQL プロパティの値列をダブルクリックする

SQL プロパティの省略記号をクリックする

SQL 文の入力は何行になっても，また 1 行でもかまいません。ただし，複数行に分けて文を入力した方が，読みやすくなり，変更やデバッグが簡単になります。［OK］を選択して，入力したテキストを SQL プロパティに代入します。

通常 SQL プロパティには，一度に 1 つの完全な SQL 文しか入れられません。ただし，SQL 文は必要であれば複雑にできます（たとえば，WHERE 節付きの SELECT 文では，AND や OR などの論理演算子を入れ子にして複数使えます）。一部のサーバーでは複数の文を許可する「バッチ」構文をサポートしています。つまり，このような構文を提供しているサーバーでは，SQL プロパティに複数の文を入力できます。

メモ	Delphi Client/Server Suite の場合，ビジュアルクエリービルダでもデータベースのテーブルや項目の表示形式に基づいて問い合わせを作成できます。ビジュアルクエリービルダを使うには，問い合わせコンポーネントを選択し，それを右クリックしてコンテキストメニューを表示し，［クエリービルダー（Q）］を選択します。ビジュアルクエリービルダの使い方についての詳細は，オンラインヘルプを参照してください。


Specifying an SQL statement at run time
Specifying an SQL statement at run time1095009

Section topics 	参照

実行時に SQL プロパティを設定する方法には，アプリケーションが SQL プロパティを直接設定する方法と，SQL プロパティの LoadFromFile メソッドを呼び出してファイルから SQL 文を読み出す方法の 2 つがあります。

Setting the SQL property directly1095010

実行時に SQL プロパティを設定する手順は次のとおりです。

1.	Close を呼び出して問い合わせを非アクティブにします。問い合わせがすでに非アクティブ状態でも Close を呼び出すのは問題ありません。新しい SQL 文で問い合わせを再度開いたり再実行するには必ず Close を呼び出す必要があります。

2.	SQL プロパティの Clear メソッドを呼び出して問い合わせコンポーネントの現在の SQL 文を削除します。

3.	SQL プロパティの Add メソッドを呼び出して，1 つまたは複数の文字列を SQL プロパティに挿入および追加して，新しい SQL 文を作成します。

4.	Open または ExecSQL を呼び出して問い合わせを実行します。

次のコードはこの手順を示しています。

CustomerQuery.Close; // アクティブなら，問い合わせを閉じる

CustomerQuery.SQL.Clear; // SQL 文があれば，それを削除する

CustomerQuery.SQL.Add('SELECT * FROM ORDERS');

CustomerQuery.SQL.Add('WHERE COMPANY = ''Sight Diver''');

CustomerQuery.Open;

メモ	問い合わせでパラメータを使う場合，問い合わせを開くか実行する前にその初期値を設定し Prepare メソッドを呼び出す必要があります。

Loading the SQL property from a file1095011

LoadFromFile メソッドを使っても，テキストファイルの SQL 文を SQL プロパティに代入することができます。たとえば，次のようにします。

CustomerQuery.Close;

CustomerQuery.SQL.Clear;

CustomerQuery.SQL.LoadFromFile('C:\ORDERS.TXT');

CustomerQuery.Open;

メモ	ファイル内の SQL 文がパラメータ付きの問い合わせの場合，問い合わせを開くか実行する前にパラメータの初期値を設定し，Prepare を呼び出します。


Setting parameters
Setting parameters1095012

Section topics 	参照

パラメータ付きの SQL 文にはパラメータつまり変数が含まれており，その値は設計時または実行時に変えることができます。パラメータは，SQL 文の中に現れる列名やデータ値（比較用の WHERE 節で使われるものなど）の代わりになることができます。通常，パラメータは文に渡すデータ値の代わりとして使います。たとえば，次の INSERT 文では，挿入する値がパラメータで渡されています。

INSERT INTO COUNTRY (NAME, CAPITAL, POPULATION)

VALUES (:name, :capital, :population)

この SQL文では，:name，:capital，:population はアプリケーションで実行時に文へ渡す実際の値の代わりのプレースホルダです。パラメータ付きの問い合わせを初めて実行する前に，アプリケーションは Prepare メソッドを呼び出して，パラメータの現在の値を SQL 文に結合する必要があります。結合とは，問い合わせの実行速度を改善するように BDE とサーバーが文とそのパラメータのリソースを割り当てることを意味します。


Supplying parameters at design time
Supplying parameters at design time1095013

Section topics 	参照

設計時に問い合わせパラメータを入力するには，問い合わせパラメータエディタを呼び出すのがもっとも簡単で安全です。問い合わせパラメータエディタには，正しい順序でパラメータが示されるので，そこでパラメータへ値を代入できます。設計時にパラメータを定義すると，問い合わせが自動的に再準備されます。

問い合わせパラメータエディタを呼び出す手順は次のとおりです。

1.	問い合わせコンポーネントを選択します。

2.	コンポーネントを右クリックしてコンテキストメニューを呼び出します。

3.	［パラメータの定義（P）］を選択します。

以前に定義されたパラメータを持たない問い合わせの場合，［パラメータ名（P）］リストボックスは空です。問い合わせにパラメータがすでに定義済みの場合は，リストボックスにパラメータ名が表示されます。

［データの種類（D）］コンボボックスには，リストボックスで選択されたパラメータの BDE データ型が示されます。パラメータそれぞれにデータ型を設定しなければなりません。一般に，BDE のデータ型はサーバーのデータ型と一致します。BDE とサーバーのデータ型のマッピングについては，オンラインヘルプを参照してください。

［値（V）］編集ボックスを使うと，選択したパラメータの値を入力できます。［ヌル値（N）］チェックボックスにチェックマークを付けると，選択したパラメータのデータ型でヌル値が許されていれば，ヌル値を設定できます。値がヌルであっても，パラメータごとに必ず値を入力しなければなりません。

最後に［OK］を選択してパラメータ定義を終了します。


Supplying parameters at run time
Supplying parameters at run time1095014

Section topics 	参照

実行時にパラメータを作成するには，次のどれかを使います。

ParamByName メソッド（パラメータ名に基づいてパラメータ値を代入する場合）

Params プロパティ（パラメータ順に基づいてパラメータ値を代入する場合）

Params.ParamValues プロパティ（パラメータ名に基づいてパラメータ値を代入する場合）。バリアント型を使用するため，値をキャストする必要がありません

たとえば，次のコードは ParamByName を使って編集ボックスのテキストを Company 項目に代入します。

Query1.ParamByName('Company').AsString := Edit1.Text;

Params プロパティを使う場合は次のようなコードになります（Company が問い合わせの最初のパラメータと想定しています）。

Query1.Params[0].AsString := Edit1.Text;

Params.ParamValues プロパティを使う場合は次のようなコードになります。paramValues はバリアント型であるため，型変換は自動的に行われます。

Query1.Params.ParamValues['Company'] := Edit1.Text;

Assigning values to parameters based on parameter name1095015

ParamByName はアプリケーションがパラメータ名に基づいてパラメータ値を代入できるようにする関数です。この関数を使うと，値を代入するパラメータの実際の順序は知らなくてすむので直接 Params プロパティを使うより簡単で安全です。Params プロパティで文字列配列に直接インデックス付けするときに必要なようにパラメータの順序位置を指定するのではなく，パラメータ名を ParamByName への引数として渡します。

たとえば，CountryQuery という名前の問い合わせコンポーネントの SQL プロパティに次の文があるとします。

INSERT INTO COUNTRY (NAME, CAPITAL, POPULATION)

VALUES (:name, :capital, :population)

次の文は指定されたパラメータにパラメータ値を代入します。

CountryQuery.ParamByName('name').AsString := 'Lichtenstein';

CountryQuery.ParamByName('capital').AsString := 'Vaduz';

CountryQuery.ParamByName('population').AsInteger := 420000;

Assigning values to parameters based on parameter order1095016

パラメータ付きの問い合わせを作成すると，Params プロパティ内にその問い合わせのパラメータオブジェクト配列が作成されます。Params は TParam オブジェクトのゼロから始まる配列で，問い合わせの各パラメータの要素を持っています。最初のパラメータは Params[0]，2 番目のパラメータは Params[1] という具合になります。

たとえば，次の問い合わせ文があるとします。

INSERT INTO COUNTRY (NAME, CAPITAL, POPULATION)

VALUES (:name, :capital, :population)

アプリケーションは次のようにパラメータのそれぞれに値を指定できます。

CountryQuery.Params.Items[0].AsString := 'Lichtenstein';

CountryQuery.Params.Items[1].AsString := 'Vaduz';

CountryQuery.Params.Items[2].AsInteger := 420000;

以上の文は，「Lichtenstein」を :name パラメータに，「Vaduz」を :capital パラメータに，「420000」を :population パラメータにそれぞれ代入します。


Using a data source to bind parameters
Using a data source to bind parameters1095017

Section topics 	参照

パラメータ付きの問い合わせのパラメータ値を設計時に設定しなかった場合，Delphi はその値を問い合わせコンポーネントの DataSource プロパティに基づいて与えようとします。DataSource は値を指定していないパラメータの名前と一致する項目名の検索場所として別のテーブルコンポーネントまたは問い合わせコンポーネントを指定します。この検索データセットは，それを使う問い合わせコンポーネントを作成する前に作成してデータを入れる必要があります。検索データセットで一致が見つかると，Delphi はそのデータソースが指す現在のレコードの項目の値へパラメータ値を結合します。

DataSource プロパティを使ってマスターリンク形式の問い合わせをリンクする方法を理解するため，単純なアプリケーションを作成してみます。このアプリケーションのデータモジュールを LinkModule とし，次の SQL プロパティを持つ OrdersQuery という問い合わせコンポーネントがデータモジュール内にあるとします。

SELECT CustNo, OrderNo, SaleDate

FROM Orders

WHERE CustNo = :CustNo

LinkModule データモジュールには以下のコンポーネントもあります。

CUSTOMER.DB テーブルにリンクした CustomersTable という名前の TTable データセットコンポーネント

OrdersSource という名前の TDataSource コンポーネント。OrdersSource の DataSet プロパティは OrdersQuery を指す

CustomersTable にリンクした CustomersSource という名前の TDataSource。OrdersQuery コンポーネントの DataSource プロパティも CustomersSource に設定される。これは，OrdersQuery をリンク問い合わせにする設定である

このアプリケーションには，2 つのデータグリッド（CustomersSource にリンクした Customers Table グリッドと OrdersSource にリンクした Order Query グリッド）を持つ LinkedQuery フォームもあるとします。

図に，このアプリケーションの設計時の外観を示します。

設計時のマスターリンク問い合わせフォームとデータモジュール例

メモ	このアプリケーションを構築する場合，問い合わせコンポーネントの作成前にテーブルコンポーネントとそのデータソースを作ってください。

このアプリケーションをコンパイルする場合，実行時には OrdersQuery の SQL 文の中にある :CustNo パラメータには値が代入されないので，Delphi は CustomersSource が指すテーブルの列を調べて，名前でパラメータを一致させようとします。CustomersSource はそのデータを CustomersTable から取得し，CustomersTable はそのデータを CUSTOMER.DBテーブルから取得します。CUSTOMER.DB には「CustNo」という列があるので，CustomersTable データセットの現在のレコードの CustNo 項目の値が，OrdersQuery SQL 文の :CustNo パラメータに代入されます。グリッドはマスターリンクの関係でリンクされます。実行時には，Customers Table グリッドで別のレコードを選択するたびに，OrdersQuery の SELECT 文が現在の顧客番号に基づいてすべての注文を取り出すように実行されます。


Executing a query
Executing a query1095018

Section topics 	参照

SQL プロパティに SQL 文を指定し，問い合わせにパラメータを設定したら，その問い合わせを実行できます。問い合わせが実行されると，BDE はアプリケーションから SQL 文を受け取り処理します。

メモ	初めて問い合わせを実行する場合，その前に Prepare メソッドを呼び出して問い合わせの処理速度を高めることができます。Prepareを呼ぶと，BDE とデータベースサーバーの両方に対して問い合わせ用のシステムリソースを事前に割り当てる等の初期設定を行います。問い合わせの準備については，「問い合わせの準備」を参照してください。

以降の各節では，設計時と実行時の静的 SQL 文と動的 SQL 文の実行について説明します。


Executing a query at design time
Executing a query at design time1095019

Section topics 	参照

設計時に問い合わせを実行するには，Active プロパティを True に設定します。

問い合わせの結果があれば，問い合わせコンポーネントに関連付けられたデータベース対応コントロールに表示されます。


Executing a query at runtime
Executing a query at runtime1095020

Section topics 	参照

実行時に問い合わせを行うには，以下のどちらかを呼び出します。

Open　結果セットを返す問い合わせ（SELECT など）を実行する

ExecSQL　結果セットを返さない問い合わせ（INSERT，UPDATE，DELETE など）を実行する

メモ	実行時に問い合わせが結果セットを返すかどうかが設計時にはわからない場合は，try...except ブロックに両方の問い合わせ実行文を記述してください。try 節に Open メソッドへの呼び出しを入れ，except 節に ExecSQL メソッドを入れます。文を 2 回実行しないようにするには（たとえば，空の結果セットの場合），except 節で ExecSQL メソッドを実行する前に，ENoResultSet の例外を調べてみてください。

Executing a query that returns a result set1095021

結果セットを返す問い合わせ（SELECT 文など）を実行する手順は次のとおりです。

1.	Close を呼び出して問い合わせが開いていないことを確認する。問い合わせがすでに開いている場合は，それを閉じてから再度開く必要がある。問い合わせをいったん閉じてから再度開くと，サーバーから最新のデータを取り出すことができる

2.	Open を呼び出して問い合わせを実行する

たとえば，次のようにします。

CustomerQuery.Close;

CustomerQuery.Open; // 結果セットを返す

結果セットの操作については，「双方向カーソルの無効化」を参照してください。結果セットの編集と更新については，「結果セットの操作」を参照してください。

Executing a query without a result set1095022

結果セットを返さない問い合わせ（INSERT，UPDATE，DELETE など）を実行するには，Open を呼び出して問い合わせを実行する

たとえば，次のようにします。

CustomerQuery.ExecSQL; // 結果セットを返さない


Preparing a query
Preparing a query1095023

Section topics 	参照

問い合わせの準備は，問い合わせの実行前に行いますが省略することもできます。問い合わせが準備されると，SQL 文とそのパラメータがある場合，解析し，リソースを割り当て，効率を上げるために BDE に送られます。BDE はデータベースサーバーに対して問い合わせの準備をするように通知します。サーバーも問い合わせ用にリソースを割り当てることができます。このように準備をすると，特に更新可能な問い合わせの処理速度が高まり，アプリケーションが高速になります。

アプリケーションは Prepare メソッドを呼び出して問い合わせを準備できます。問い合わせを準備しないと，Open または ExecSQL を初めて呼び出したときに Delphi によって問い合わせが自動的に準備されます。しかし，プログラミングで明示的に問い合わせを準備する方が望ましいでしょう。このようにして自分でコードを記述すれば，意図する問い合わせを明確にできます。たとえば，次のようにします。

CustomerQuery.Close;

if not CustomerQuery.Prepared then

CustomerQuery.Prepare;

CustomerQuery.Open;

この例では，問い合わせコンポーネントの Prepared プロパティを調べて問い合わせがすでに準備されているかどうか確認します。準備されている場合，Prepared は Trueとなります。まだ準備されていない場合は，Open を呼び出す前に Preare メソッドを呼び出します。


Unpreparing a query to release resources
Unpreparing a query to release resources1095024

Section topics 	参照

UnPrepare メソッドは Prepared プロパティを False に設定します。UnPrepare を使うと以下のことができます。

SQL プロパティを再実行する前に必ず準備し直すようにする

SQL 文に割り当てられている内部リソースを解放することを BDE に通知する

SQL 文に割り当てられていたすべてのリソースを解放することをサーバーに通知する

問い合わせの準備を解除するには次のコードを指定します。

CustomerQuery.UnPrepare;

メモ	問い合わせの SQL プロパティのテキストを変更すると，Delphi は問い合わせを自動的に閉じて準備を解除します。


Creating heterogenous queries
Creating heterogenous queries1095025

Section topics 	参照

Delphi では，異種間の問い合わせがサポートされています。つまり，複数のデータベースにあるテーブルに対して問い合わせができます。異種間の問い合わせでは，異なるサーバーにあるテーブルだけでなく異なる種類のサーバーのテーブルさえも結合できます。たとえば，Oracle データベースのテーブル，Sybase データベースのテーブル，ローカル dBASE テーブルを含む異種間の問い合わせなどが考えられます。異種間の問い合わせを実行すると，BDE がローカル SQL を使ってその問い合わせを解析して処理します。したがって，拡張されたサーバー別の SQL 構文はサポートされていません。

異種間の問い合わせを実行する手順は次のとおりです。

1.	ローカルディレクトリを参照する BDE 標準エリアスを定義し，そのエリアスを問い合わせコンポーネントの DatabaseName プロパティに使います。BDE エリアスを定義するにはデータベースエクスプローラを使います。

2.	問い合わせでアクセスするデータベースごとに BDE エリアスを別々に定義します。

3.	実行する SQL 文を SQL プロパティに指定します。SQL 文の各テーブル名の前には，そのテーブルがあるデータベースの BDE エリアスを付けます。

4.	問い合わせ用のパラメータを Params プロパティに設定します。

5.	 初めて問い合わせを実行する前に Prepare を呼び出して，その問い合わせを実行するための準備をします。

6.	実行する問い合わせの種類に応じて Open または ExecSQL を呼び出します。

たとえば，CUSTOMER テーブルのある Oracle データベースに Oracle1 というエリアスを定義し，ORDERS テーブルのある Sybase データベースに Sybase1 というエリアスをそれぞれ定義したとします。この 2 つのテーブルに対する単純な問い合わせは次のようになります。

SELECT CUSTOMER.CUSTNO, ORDERS.ORDERNO

FROM ":Oracle1:CUSTOMER", ":Sybase1:ORDERS"

WHERE CUSTNO = 1503


Improving query performance
Improving query performance1095026

Section topics 	参照

問い合わせの実行速度を向上させるための実行方法には以下の 2 通りがあります。

結果セットを逆戻りする必要がない場合は，問い合わせの UniDirectional プロパティを True に設定する。BDE はデフォルトで双方向カーソルをサポートしているので，デフォルトでは UniDirectional は False です。

実行前に問い合わせを準備する。これは，単一の問い合わせを何度も実行する場合に特に役立ちます。問い合わせの準備は，それを最初に使う前に一度だけ必要です。問い合わせの準備については，「問い合わせの準備」を参照してください。


Disabling bidirectional cursors
Disabling bidirectional cursors1095027

Section topics 	参照

UniDirectional プロパティは，Delphi の問い合わせで BDE 双方向カーソルが有効かどうかを決定します。問い合わせが結果セットを返す場合，その結果セットの最初のレコードへのポインタつまりカーソルも受け取ります。カーソルが指すレコードは現在アクティブなレコードです。現在のレコードは，結果セットのデータソースに関連付けられたデータベース対応コンポーネントに項目値が表示されるレコードです。

UniDirectional はデフォルトでは False で，結果セットのカーソルがそのレコード間を前後両方に移動できることを表します。双方向カーソルのサポートには，追加の処理がある程度必要なため，問い合わせの速度がやや低下する可能性があります。問い合わせの処理速度を向上させるために，UniDirectional を True に設定して，カーソルの動きを結果セットの前方向だけに制限することができます。

結果セットを逆戻りして参照する必要がない場合は，問い合わせの UniDirectional プロパティを True に設定できます。UniDirectional は問い合わせを準備して実行する前に設定します。次のコードでは，問い合わせの準備と実行の前に UniDirectional を設定しています。

if not CustomerQuery.Prepared then

begin

CustomerQuery.UniDirectional := True;

CustomerQuery.Prepare;

end;

CustomerQuery.Open; // 単方向カーソルを持つ結果セットを返す


Working with result sets
Working with result sets1095028

Section topics 	参照

デフォルトでは，問い合わせが返す結果セットは読み出し専用です。アプリケーションはデータベース対応コントロールに結果セットからの項目値を表示できますが，ユーザーはその値を編集できません。結果セットの編集を可能にするには，アプリケーションで「ライブ」結果セットを要求しなければなりません。


Enabling editing of a result set
Enabling editing of a result set1095029

Section topics 	参照

データベース対応コントロールでユーザーが編集可能な結果セットを要求するには，問い合わせコンポーネントの RequestLive プロパティを True に設定します。RequestLive を True に設定することでライブ結果セットが保証されるわけではありません。しかし，BDE はできるだけ要求に応えようとします。問い合わせがローカル SQL パーサーを使っているかサーバーの SQL パーサーを使っているかにより，ライブ結果セット要求はある程度制限されます。Paradox または dBASE に対して実行される異種間の結合と問い合わせは BDE がローカル SQL を使って解析します。リモートデータベースサーバーに対する問い合わせの場合は，サーバーがその問い合わせを解析します。

ライブ結果セットを要求し，成功した場合，Delphi はその問い合わせコンポーネントの CanModify プロパティを True に設定します。

アプリケーションがライブ結果セットを要求しても，SELECT 文の構文でそれが許されない場合，BDE は以下のどちらかを返します。

読み出し専用結果セット（Paradox または dBASE に対する問い合わせの場合）

エラーコード（リモートサーバーに対するパススルー SQL 問い合わせの場合）


Local SQL requirements for a live result set
Local SQL requirements for a live result set1095030

Section topics 	参照

ローカル SQL パーサーを使う問い合わせの場合，BDE は単一テーブルとマルチテーブルの両方の問い合わせに対して更新可能なライブ結果セットを拡張してサポートします。ローカル SQL パーサーは，1 つまたは複数の dBASE テーブルか Paradox テーブルに対して問い合わせる場合，または問い合わせのテーブル名の前に BDE データベースエリアスが付いている 1 つまたは複数のリモートサーバーテーブルに対して問い合わせる場合に使います。以降の各節では，ローカル SQL のライブ結果セットを返すために必要な制限事項について説明します。

Restrictions on live queries1095031

問い合わせに以下のものが含まれていなければ，単一のテーブルまたはビューに対する問い合わせでライブ結果セットが返されます。

JOIN 節，UNION 節，INTERSECT 節，MINUS 節

SELECT 文の DISTINCT 節

集合関数

更新できない基本テーブルまたはビュー

GROUP BY 節または HAVING節

副問い合わせ

インデックスに基づいていない ORDER BY 節

Restrictions on live joins1095032

以下の場合，結合でライブ結果セットが返されます。

2 つだけのテーブルを結合する

すべての結合が左から右の順に結合される外部結合になっている

Paradox テーブルと dBASE テーブルのすべての結合を既存のインデックスで満足できる

出力順が定義されていない

結合する各テーブルが基本テーブルである

ライブ問い合わせに適用されるすべての制限を満足している。詳細については，「ライブ問い合わせの制限」を参照


Remote server SQL requirements for a live result set
Remote server SQL requirements for a live result set1095033

Section topics 	参照

パススルー SQL を使う問い合わせ（リモートデータベースサーバーだけに対するすべての問い合わせを含む）の場合，ライブ結果セットは SQL-92 の定義に基づく標準とサーバーが規定する追加の制限に限定されます。

ライブ結果セットを返すためには，問い合わせに以下のものを含まないことが SQL-92 の制限として満足されなければなりません。

SELECT 文の DISTINCT 節

集合関数

複数の基本テーブルまたは更新可能なビューへの参照

GROUP BY 節または HAVING 節

FROM節でテーブルを参照している副問い合わせ

相互に関連し合った副問い合わせ


Restrictions on updating a live result set
Restrictions on updating a live result set1095034

Section topics 	参照

問い合わせがライブ結果セットを返した場合に，結果セットにリンクされた項目が含まれているかまたは更新する前にインデックスを切り替えると，問い合わせの結果セットを直接更新できなくなることがあります。そのような場合，結果セットを読み出し専用結果セットとして扱い，それに応じた方法で更新できます。


Updating a read-only result set
Updating a read-only result set1095035

Section topics 	参照

キャッシュアップデートを使うと，読み出し専用の問い合わせ結果から元テーブルへの更新を行うことができます。

問い合わせコンポーネントに関連付けられている読み出し専用結果セットを更新する手順は次のとおりです。

1.	TUpdateSQL コンポーネントをアプリケーション内のデータモジュールに追加して，読み出し専用データセットへの更新を通知できるようにします。

2.	結果セットの SQL 更新文を更新コンポーネントの ModifySQL プロパティ，InsertSQL プロパティ，DeleteSQL プロパティに入力します。

3.	問い合わせコンポーネントの CachedUpdate プロパティを True に設定します。

キャッシュアップデートの使い方については，「キャッシュアップデートの操作」を参照してください。1095036


See also1095037

TQuery

TUpdateSQL

サーバー開発者用の問い合わせ

デスクトップ開発者用の問い合わせ


Working with stored procedures
 Working with stored procedures1081001

Section topics 	参照

この章では，データベースアプリケーション内での TStoredProc データセットコンポーネントの使い方について説明します。ストアドプロシージャコンポーネントは TDataSet の下位コンポーネントで，その基本動作を TDataSet から継承します。

ストアドプロシージャコンポーネントは，Sybase，Microsoft SQL Server，Oracle，InterBase などのリモートデータベースサーバーにあるストアドプロシージャをカプセル化します。ストアドプロシージャコンポーネントを使うと，Delphi アプリケーションはサーバーのストアドプロシージャを実行できます。

ストアドプロシージャは文の集まりで，リモートサーバーのデータベースメタデータ（テーブル，インデックス，ドメインなど）の一部として格納されます。ストアドプロシージャは，よく繰り返されるデータベース関連の作業をサーバー上で実行し，結果を Delphi データベースアプリケーションなどのクライアントアプリケーションに渡します。

ストアドプロシージャには普通，処理用のパラメータが渡されます。通常は，結果データセットのほかに出力パラメータを返しますが，一部のストアドプロシージャは結果パラメータも返します。アプリケーションはデータセットのレコードをデータベース対応コントロールに表示することができ，出力パラメータの検査と処理もできます。サーバーでのストアドプロシージャのサポートについての詳細は，サーバーのマニュアルを参照してください。

メモ	InterBase は 2 種類のストアドプロシージャをサポートしています。そのうちの一方は，SELECT 文のコンテキストの中で呼び出されるので，選択プロシージャと呼ばれます。InterBase の選択プロシージャを Delphi で使うには，TStoredProcコンポーネントのかわりに TQuery コンポーネントを使ってください。


When should you use stored procedures?
When should you use stored procedures?1081002

Section topics 	参照

サーバーがストアドプロシージャを定義している場合，アプリケーションのニーズに合っていればそのストアドプロシージャを使ってください。データベースサーバー開発者はストアドプロシージャを作成して，よく繰り返されるデータベース関連の作業を処理します。多くの場合，データベーステーブルの多数の行に作用する操作，すなわち集合関数や算術関数を使う操作はストアドプロシージャを使用します。アプリケーションが使うリモートデータベースサーバーにストアドプロシージャがある場合は，アプリケーションでストアドプロシージャを利用してください。ストアドプロシージャの提供する機能の一部がおそらく必要になるでしょう。また，ストアドプロシージャを利用すると以下のようにできるので，データベースアプリケーションの処理効率の向上が見込まれます。

サーバーの処理パワーと速度を利用する

データのあるサーバーで処理を行うことでネットワークトラフィック量を減らす

たとえば，単一の値（数多くのレコードにわたる値の標準偏差）を計算する必要のあるアプリケーションを考えてみます。この関数を Delphi アプリケーションで実行するには，計算で使われるすべての値をサーバーから取り出し，計算しなければならず，その結果ネットワークトラフィックの量が増えます。アプリケーションが必要とするのは最終結果，つまり標準偏差を表す単一の値だけなので，サーバーが持つストアドプロシージャがそこに格納されているデータを読み出し，計算し，アプリケーションに単一値を渡した方がずっと効率的です。

サーバーでのストアドプロシージャのサポートについての詳細は，サーバーのデータベースのマニュアルを参照してください。


Using a stored procedure
Using a stored procedure1081003

Section topics 	参照

サーバーにあるストアドプロシージャにアクセスするには，アプリケーションは以下のことを行わなければなりません。

1.	ストアドプロシージャコンポーネントをインスタンス化し，必要であればサーバーにあるストアドプロシージャに関連付けます。ストアドプロシージャの作成についての詳細は，「ストアドプロシージャコンポーネントの作成」を参照してください。

2.	必要であればストアドプロシージャコンポーネントに入力パラメータ値を指定します。ストアドプロシージャコンポーネントをサーバー上のストアドプロシージャに関連付けていない場合，パラメータの名前やデータ型などの入力パラメータの補足情報を指定しなければなりません。入力パラメータ情報の指定についての詳細は，「設計時のパラメータ情報の設定」を参照してください。

3.	ストアドプロシージャを実行します。

4.	結果パラメータと出力パラメータを処理します。ほかのデータセットコンポーネントの場合と同様，サーバーから返された結果データセットの検査もできます。結果パラメータと出力パラメータについての詳細は，「出力パラメータと結果パラメータへのアクセス」を参照してください。データセットにあるレコードの表示についての詳細は，「結果データセットへのアクセス」を参照してください。


Creating a stored procedure component
Creating a stored procedure component1081004

Section topics 	参照

データベースサーバー上のストアドプロシージャ用にストアドプロシージャコンポーネントを作成する手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページにあるストアドプロシージャコンポーネントをデータモジュールに入れます。

2.	必要であればストアドプロシージャコンポーネントの DatabaseName プロパティをストアドプロシージャが中で定義されるデータベースの名前に設定します。DatabaseName は BDE エリアスでなければなりません。

通常は DatabaseName プロパティを指定する必要があります。ただし，実行するアプリケーションに対応したサーバーデータベースが現在利用できない場合，DatabaseName を省略して設計時にストアドプロシージャの名前と入力，出力，結果の各パラメータを指定することによってでも，ストアドプロシージャコンポーネントの作成と設定ができます。入力パラメータについての詳細は，「入力パラメータの使い方」を参照してください。出力パラメータについての詳細は，「出力パラメータの使い方」を参照してください。結果パラメータについての詳細は，「結果パラメータの使い方」を参照してください。

3.	必要であれば StoredProcName プロパティを，使うストアドプロシージャの名前に設定します。DatabaseName プロパティの値を指定した場合，StoredProcName プロパティのドロップダウンリストからストアドプロシージャの名前を選択できます。

DatabaseName プロパティを指定した場合，通常は StoredProcName プロパティを指定する必要があります。

4.	Params プロパティの値ボックスをダブルクリックして StoredProc パラメータエディタを呼び出し，ストアドプロシージャの入力パラメータと出力パラメータを調べます。手順 3 でストアドプロシージャの名前を指定していない場合，または手順 2 で DatabaseName プロパティに指定したサーバーに存在しないストアドプロシージャの名前を指定した場合，StoredProc パラメータエディタを呼び出すと空になっています。

メモ	サーバーのストアドプロシージャの作成，編集，検査は，SQL エクスプロータを使って行うこともできます。

すべてのサーバーがパラメータまたはパラメータ情報を Delphi に返すわけではありません。サーバーがストアドプロシージャに関してどのような情報をクライアントアプリケーションに返すかについての詳細は，サーバーのマニュアルを参照してください。

メモ	手順 2 で DatabaseName プロパティを指定していない場合，StoredProc パラメータエディタを使って設計時にパラメータを設定しなければなりません。設計時のパラメータの設定についての詳細は，「設計時のパラメータ情報の設定」を参照してください。


Understanding stored procedure parameters
Understanding stored procedure parameters1081005

Section topics 	参照

ストアドプロシージャには以下の 4 種類のパラメータを関連付けることができます。

入力パラメータ	処理用に値をストアドプロシージャに渡すために使います。

出力パラメータ	ストアドプロシージャが戻り値をアプリケーションに渡すために使います。

入出力パラメータ	処理用に値をストアドプロシージャに渡すために使い，さらにストアドプロシージャが戻り値をアプリケーションに渡すために使います。

結果パラメータ	一部のストアドプロシージャがエラー値または状態値をアプリケーションに返すために使います。ストアドプロシージャが返せる結果パラメータは 1 つだけです。

ストアドプロシージャが特定の種類のパラメータを使うかどうかは，データベースサーバー上のストアドプロシージャの汎用言語実装と，ストアドプロシージャの具体的なインスタンスの両方によって決まります。たとえば，どのサーバーでも，個々のストアドプロシージャの実装では入力パラメータを使う場合と使わない場合があります。これに対して，サーバーごとにパラメータの使い方が決まっている場合もあります。たとえば，MS-SQL Server と Sybase ではストアドプロシージャは必ず結果パラメータを返しますが，InterBase ではストアドプロシージャが結果パラメータを返すことはありません。

メモ	一部のストアドプロシージャは出力パラメータと結果パラメータだけでなくデータセットも返します。アプリケーションはデータセットのレコードをデータベース対応コントロールで表示できますが，出力パラメータと結果パラメータを別々に処理しなければなりません。データベース対応コントロールでのレコードの表示についての詳細は，「結果データセットへのアクセス」を参照してください。


Using input parameters
Using input parameters1081006

Section topics 	参照

ほとんどのストアドプロシージャには，処理中に使う 1 つ以上の入力パラメータを渡す必要があります。たとえば，2 つの銀行口座間で資金を移動するストアドプロシージャには，引き出し元の口座番号，預金先の口座番号，移動する金額の 3 つの入力パラメータが必要になります。

設計時に DatabaseName プロパティと StoredProcName プロパティを設定してリモートデータベースサーバーに接続する場合，StoredProc パラメータエディタを使って各入力パラメータの名前とデータ型を表示できます。また，ストアドプロシージャを実行するときにサーバーに渡す入力パラメータの値を設定することもできます。

重要	サーバーが示した入力パラメータの名前またはデータ型を変更しないでください。変更すると，ストアドプロシージャを実行したときに例外が生成されます。

Informix などの一部のサーバーはパラメータの名前もデータ型も示しません。この場合は，SQL エクスプローラを使ってサーバー上のストアドプロシージャのソースコードを表示し，入力パラメータとデータ型を確認します。詳細は SQL エクスプローラのヘルプを参照してください。

リモートサーバー上のストアドプロシージャからパラメータリストを受け取らない場合（サーバーに接続していない場合など），StoredProc パラメータエディタを呼び出し，必要な各入力パラメータを一覧表示して，それぞれにデータ型と値を割り当てなければなりません。StoredProc パラメータエディタを使ったパラメータの作成についての詳細は，「設計時のパラメータ情報の設定」を参照してください。


Using output parameters
Using output parameters1081007

Section topics 	参照

ほとんどのストアドプロシージャは 1 つ以上の出力パラメータを返します。出力パラメータが表すのは，データセットを返さないストアドプロシージャの単項の戻り値，データセットも返すストアドプロシージャの戻り値の集合，ストアドプロシージャが返すデータセット内の個々のレコードとは直接的な対応関係のない値のいずれかです。この点では各サーバーのストアドプロシージャの実装に違いがあります。

設計時に DatabaseName プロパティと StoredProcName プロパティを設定してリモートデータベースサーバーに接続する場合，StoredProc パラメータエディタを使って各出力パラメータの名前とデータ型を表示できます。サーバーが示した出力パラメータの名前またはデータ型を変更しないでください。変更すると，ストアドプロシージャを実行したときに例外が生成されます。

メモ	Informix のストアドプロシージャのソースコードでは出力パラメータを返すことが示されていますが，StoredProc パラメータエディタには出力パラメータ情報は表示されません。BDE が Informix の出力パラメータを，アプリケーションのデータベース対応コントロールで表示可能な単一レコードのデータセットに自動的に変換します。

リモートサーバー上のストアドプロシージャからパラメータリストを受け取らない場合（サーバーに接続していない場合など），StoredProc パラメータエディタを呼び出し，必要な各入力パラメータを一覧表示して，それぞれにデータ型と値を割り当てなければなりません。


Using input/output parameters
Using input/output parameters1081008

Section topics 	参照

入出力パラメータはアプリケーションがサーバー上のストアドプロシージャに値を渡すために使い，さらにサーバーが値の各集合をアプリケーションに返すために使います。データベースサーバーが入出力パラメータをサポートまたは使用しているかどうかについての詳細は，データベースサーバーのマニュアルを参照してください。

リモートサーバー上のストアドプロシージャからパラメータリストを受け取らない場合（サーバーに接続していない場合など），StoredProc パラメータエディタを呼び出し，必要な各入力パラメータを一覧表示して，それぞれにデータ型と値を割り当てなければなりません。


Using the result parameter
Using the result parameter1081009

Section topics 	参照

一部のストアドプロシージャは出力パラメータとデータセットだけでなく単一の結果パラメータも返します。通常，結果パラメータはストアドプロシージャの実行に基づくエラー状態または処理レコード数を示すために使われます。データベースサーバーが結果パラメータをサポートしているかどうか，またどのようにサポートしているかについての詳細は，データベースサーバーのマニュアルを参照してください。

リモートサーバー上のストアドプロシージャからパラメータリストを受け取らない場合（サーバーに接続していない場合など），StoredProc パラメータエディタを呼び出し，必要な入力パラメータを一覧表示して，データ型と値を割り当てなければなりません。


Viewing parameter information at design time
Viewing parameter information at design time1081010

Section topics 	参照

Delphi からデータベースサーバーにアクセスできる場合，ストアドプロシージャが使うパラメータの情報を表示する方法は通常 2 つあります。

SQL エクスプローラを呼び出して，リモートサーバーにあるストアドプロシージャのソースコードを表示する。ソースコードには，各パラメータのデータ型と名前を識別するパラメータ宣言が含まれる

ストアドプロシージャコンポーネントの DatabaseName プロパティをデータベースサーバーの BDE エリアスに設定し，StoredProcName プロパティを表示対象のストアドプロシージャの名前に設定してから，Params プロパティ値をダブルクリックして StoredProc パラメータエディタを呼び出す

BDE ネイティブのドライバを使用している場合は，SQL エクスプローラを使うと，データベースサーバーにあるストアドプロシージャをいつでも調べられます（ODBC ドライバを使っている場合は，SQL エクスプローラでストアドプロシージャを調べることはできません）。これに対して，StoredProc パラメータエディタに返されるストアドプロシージャ関連情報の量はデータベースサーバーによって異なります。たとえば，Informix サーバーが返すのはストアドプロシージャの入力パラメータの数だけで，そのパラメータの名前やデータ型は返しません。

StoredProc パラメータエディタを呼び出す手順は次のとおりです。

1.	ストアドプロシージャコンポーネントを選択します。

2.	ストアドプロシージャコンポーネントのコンテキストメニューの［パラメータの定義(P)］を選択するか，オブジェクトインスペクタで Params プロパティの値ボックスをダブルクリックします。

［パラメータ名(P)］リストボックスには，選択されたストアドプロシージャのすべての入力パラメータ，出力パラメータ，入出力パラメータ，結果パラメータが表示されます。すべてのストアドプロシージャがどの種類のパラメータも使うわけではありません。パラメータの情報はサーバーから取り出されます。一部のサーバーでは，パラメータ情報の一部または全部にアクセスできません。

［パラメータの種類(T)］コンボボックスには，リストボックスで選択されたパラメータが入力，出力，入出力，結果のいずれのパラメータであるかが示されます。

メモ	Sybase，MS-SQL，Informix はパラメータの種類の情報を返しません。この情報を確認するには，SQLエクスプローラを使います。

［データの種類(Y)］コンボボックスには，リストボックスで選択されたパラメータのデータ型が示されます。

メモ	Informix はデータ型の情報を返しません。この情報を確認するには，SQL エクスプローラを使います。

［値(V)］編集ボックスを使うと，選択した入力パラメータの値を入力できます。［ヌル値(N)］チェックボックスを使うと，選択した入力パラメータのデータ型でヌル値がサポートされていれば，ヌル値を設定できます。パラメータ値の設定についての詳細は，？？13-7 ページの「設計時のパラメータ情報の設定」を参照してください。

メモ	出力パラメータと結果パラメータの値は設定できません。


Setting parameter information at design time
Setting parameter information at design time1081011

Section topics 	参照

設計時に StoredProc パラメータエディタを呼び出すと，ストアドプロシージャの実行前に入力パラメータの値を設定できます。ストアドプロシージャコンポーネントの DatabaseName プロパティを設定しない場合，または DatabaseName プロパティは設定するが，StoredProcName プロパティをサーバーが示したストアドプロシージャの名前に設定しない場合，入力パラメータの値を設定するだけでなく，パラメータの名前とデータ型も設定しなければなりません。パラメータの名前とデータ型の設定が必要な場合は，StoredProc パラメータエディタの［追加(A)］ボタンが使用可能になります。

［追加(A)］ボタンを使うと，作成するストアドプロシージャ定義にパラメータを追加できます。

新規パラメータを作成する手順は次のとおりです。

1.	［追加(A)］をクリックします。

2.	パラメータの名前を指定し，［OK］を選択します。指定した名前が［パラメータ名(P)］リストボックスに表示されます。

3.	［パラメータの種類(T)］コンボボックスでパラメータの種類として入力，出力，入出力，結果のいずれかを選択します。

4.	［データの種類(Y)］コンボボックスからパラメータのデータ型を選択します。ORACLE ストアドプロシージャから結果セットを返すには，項目型を［Cursor］に設定します。

5.	手順 3 で指定したパラメータの種類が入出力パラメータの場合，ストアドプロシージャに渡す値を［値(V)］編集ボックスで指定します。必要であればヌル値を渡すために［ヌル値(N)］チェックボックスにチェックマークを付けることができます。

［パラメータ名(P)］リストボックスに新規パラメータを追加するとすぐに，［削除(D)］ボタンと［クリア(C)］ボタンが使用可能になります。

［削除(D)］ボタンを使うと，追加したパラメータを削除できます。追加した唯一のパラメータを削除した場合，［削除(D)］ボタンと［クリア(C)］ボタンが使用不可になります。

［クリア(C)］ボタンを使うと，すべてのパラメータをリストから削除できます。追加したすべてのパラメータをクリアした場合，［削除(D)］ボタンと［クリア(C)］ボタンが使用不可になります。

追加したパラメータの定義は編集できますが，追加したパラメータはサーバーのストアドプロシージャのパラメータと一致しなければなりません。パラメータを編集するには，［パラメータ名(P)］リストボックスでパラメータを選択します。

最後に［OK］を選択してパラメータ定義を終了します。


Setting input parameter values at run time
Setting input parameter values at run time1081012

Section topics 	参照

実行時に入力パラメータを設定するには，Params プロパティに直接アクセスします。 たとえば，次のコードは編集ボックスのテキストを配列の最初の文字列に代入します。

StoredProc1.Params[0].AsString:= Edit1.Text;

次のように ParamByName メソッドを使って名前でパラメータにアクセスすることもできます。

StoredProc1.ParamByName('Company').AsString := Edit1.Text;

Params は TParams 型のオブジェクトで，TParam オブジェクトの配列が入っています。各 TParam オブジェクトは，パラメータの操作にも使える Add メソッドと Remove メソッドを持ちます。詳細は「ビジュアルコンポーネントライブラリリファレンス」を参照してください。


Preparing and executing a stored procedure
Preparing and executing a stored procedure1081013

Section topics 	参照

ストアドプロシージャを使うには，それを準備して実行します。

ストアドプロシージャの準備は以下のようにして行います。

設計時には，パラメータエディタで［OK］を選択する

実行時には，ストアドプロシージャコンポーネントの Prepare メソッドを呼び出す

たとえば，次のコードはストアドプロシージャを実行用に準備します。

StoredProc1.Prepare;

メモ	ストアドプロシージャの準備は設計時でも実行時でもできます。実際，ORACLE のオーバーロードプロシージャを使っている場合など，アプリケーションが実行時にパラメータ情報を変更する場合は，プロシージャを準備し直す必要があります。

準備したストアドプロシージャを実行するには，そのストアドプロシージャコンポーネントの ExecProc メソッドを呼び出します。次のコードは，ストアドプロシージャを準備して実行するコードを示しています。

StoredProc1.Params[0].AsString := Edit1.Text;

StoredProc1.Prepare;

StoredProc1.ExecProc;

メモ	準備する前にストアドプロシージャを実行しようとすると，自動的に準備され，その実行後に準備が解除されます。ストアドプロシージャを何回も実行するつもりの場合は，Prepare を自分で呼び出してから，そのストアドプロシージャを実行する必要がもうなくなったときに一度 UnPrepare を呼び出すだけにした方がより効率的です。

ストアドプロシージャを実行すると，以下の全部または一部が返されます。

データソースコンポーネントを使ってストアドプロシージャに関連付けられ，データベース対応コントロールに表示できる 1 件以上のレコードからなるデータセット

出力パラメータ

ストアドプロシージャの実行に関するステータス情報が入った結果パラメータ

サーバーのストアドプロシージャが返すことになっている項目を調べるには，サーバーのマニュアルを参照してください。


Binding parameters
Binding parameters1081014

Section topics 	参照

ストアドプロシージャを準備して実行した場合，その入力パラメータは自動的にサーバーのパラメータに結合されます。Sybase 上では，BLOB 型をパラメータに結合できます。

ParamBindMode プロパティを使うと，ストアドプロシージャコンポーネントのパラメータをサーバーのパラメータにどのように結合するかを指定できます。

ParamBindMode のデフォルト設定は pbmByName で，ストアドプロシージャコンポーネントからのパラメータはサーバーのパラメータと名前で一致します。通常は，これが一番簡単なパラメータ結合の方法です。

一部のサーバーは，順序値によるパラメータ結合もサポートしています。この場合，Stored Proc パラメータエディタでのパラメータの指定順が重要です。最初に指定したパラメータがサーバーの最初の入力パラメータと一致し，2 番目のパラメータがサーバーの 2 番目の入力パラメータと一致する，という具合になります。サーバーが順序値によるパラメータ結合をサポートしている場合は，ParamBindMode を pbmByNumber に設定できます。

参考	ParamBindMode を pbmByNumber に設定したい場合は，正しい順序で正しいパラメータ型を指定する必要があります。指定するパラメータの正しい順序と型を調べるために，SQL エクスプローラでサーバーのストアドプロシージャのソースコードを表示できます。


Accessing output and result parameters
Accessing output and result parameters1081015

Section topics 	参照

一部のデータベースサーバーでは，ストアドプロシージャはデータセットだけでなく出力パラメータと結果パラメータも返します。ストアドプロシージャの出力パラメータに実行時にアクセスするには，Params 文字列リストに添字を付けるか，ParamByName メソッドを使って値にアクセスできます。次の文は両方とも，出力パラメータに基づいて編集ボックスの値を設定します。

Edit1.Text := StoredProc1.Params[6].AsString;

Edit1.Text : = StoredProc1.ParamByName('Contact').AsString;


Accessing the result dataset
Accessing the result dataset1081016

Section topics 	参照

データベース対応コントロールにストアドプロシージャからの結果を表示する手順は次のとおりです。

1.	データソースコンポーネントをデータモジュールに入れます。

2.	データソースの DataSet プロパティをデータの受信元であるストアドプロシージャコンポーネントの名前に設定します。

3.	データベース対応コントロールの DataSource プロパティをデータソースコンポーネントの名前に設定します。

データベース対応コントロールはこれで，ストアドプロシージャコンポーネントの Active プロパティが True のときに，ストアドプロシージャから結果を表示できます。

メモ	Infomix のストアドプロシージャはデータセットを返しません。かわりに，出力パラメータで単項の結果を返します。出力パラメータへのアクセスについての詳細は，「出力パラメータと結果パラメータへのアクセス」を参照してください。MS-SQL Server と Sybase のストアドプロシージャは複数のデータセットを返せますが，TStoredProc はサーバーから返された最初のデータセットを受け付けるだけです。


Working with Oracle overloaded stored procedures
Working with Oracle overloaded stored procedures1081017

Section topics 	参照

ORACLE サーバーでは，ストアドプロシージャのオーバーロードができます。オーバーロードプロシージャとは同じ名前を持つ異なるプロシージャのことです。ストアドプロシージャコンポーネントの Overload プロパティを使うと，アプリケーションは実行するプロシージャを指定できます。

Overload が 0（デフォルト）の場合，オーバーロードはないと想定されます。Overload が 1 の場合，Delphi は ORACLE サーバーで同じオーバーロード名を持つ最初のストアドプロシージャを実行します。Overload が 2 の場合は，2 番目のストアドプロシージャが実行されるというようになります。

メモ	オーバーロードストアドプロシージャは異なる入力パラメータと出力パラメータをとることがあります。詳細は ORACLE サーバーのマニュアルを参照してください。


See also1081018

TStoredProc

データセットについて


Working with cached updates
Working with cached updates1082001

Section topics	参照

キャッシュアップデートを使うと，データベースからデータを取り出し，そのデータをキャッシュに格納しながらローカルで編集を行い，その後キャッシュされている変更レコードをまとめてデータベースに反映することができます。キャッシュアップデートが使用可能な場合，変更の登録やレコードの削除などのデータセットへの変更はデータセットの基礎になるテーブルに直接書き込まれるのではなく，内部キャッシュにまず格納されます。変更が一段落した時点で，アプリケーションはキャッシュされた変更をデータベースに書き込むためのメソッドを呼び出し，キャッシュをクリアします。

この章では，キャッシュアップデートをいつどのように使うのかについて説明します。また，キャッシュアップデートと TUpdateSQL コンポーネントを使うことにより，通常は変更できないデータセットを含め，ほとんどすべてのデータセットを更新できることについても説明します。


Deciding when to use cached updates
Deciding when to use cached updates1082002

Section topics	参照

キャッシュアップデートは以下の方法によりリモートデータベースサーバーでのデータアクセスの競合を減らすことを主な目的としています。

トランザクションの回数を最少にする

ネットワークトラフィックを最少にする

キャッシュアップデートはトランザクションの回数を最少にしてネットワークトラフィックを大幅に減らせる一方で，リモートサーバーを操作する一部の Delphi データベースクライアントアプリケーションには適していない場合もあります。キャッシュアップデートを使うかどうか決めるときには，以下の 3 つの事項を検討してください。

キャッシュ内のデータはアプリケーションにローカルに存在するのでトランザクションの制御を受けない。アクセスの多いクライアント／サーバー環境では，このことからアプリケーションは以下の 2 つの影響を受けます。

あるユーザーがデータのローカルコピーを編集中に，ほかのアプリケーションがサーバー上にある実際のデータにアクセスして変更してしまう

アプリケーションがそのすべての変更を書き戻すまでは，ほかのアプリケーションからは変更されたデータを見ることができない

マスターリンク関係の場合，キャッシュアップデートの適用順序を管理するのが難しくなることがある。特に，あるリンクテーブルが別のリンクテーブルのマスターテーブルであるといったネストしたマスターリンク関係の場合です。

問い合わせをベースとするデータセットにキャッシュアップデートを適用するには，アップデートオブジェクトを使う必要がある

Delphi には，このような状況を処理するために，キャッシュアップデート用とトランザクション制御用のメソッドがありますが，作業環境でアプリケーションが遭遇する可能性のある状況すべてを網羅するよう注意しなければなりません。


Understanding the cached updates process
Understanding the cached updates process1082003

Section topics	参照

この節では，アプリケーションでのキャッシュアップデート処理の概要を示します。まだキャッシュアップデートを使ったことがない場合は，この処理の説明がアプリケーションでキャッシュアップデートを実現するための指針になります。

キャッシュアップデートを使うには，アプリケーションで以下の処理をする必要があります。

1.	キャッシュアップデートを使用可能にします。キャッシュアップデートを使用可能にすると，読み出し専用トランザクションは表示に必要なだけのデータをサーバーから取得して終了します。データのローカルコピーは，表示/編集用にメモリに格納されます。キャッシュアップデートを使用可能または使用不可にする方法については，「キャッシュアップデートを使用可／不可にする」を参照してください。

2.	レコードのローカルコピーに対する表示と編集，新規レコードの挿入の許可，および既存レコードに対する削除のサポートを行います。各レコードの元のコピーとそのレコードへの編集は，どちらもメモリに格納されます。キャッシュアップデートが使用可能な場合の表示と編集については，「キャッシュアップデートの適用」を参照してください。

3.	必要に応じて，追加レコードを取得します。たとえばユーザーがレコード間をスクロールする場合，必要に応じて追加レコードを取得します。それぞれの取得は，ほかの短期間の読み出し専用トランザクションのコンテキスト内で行います。アプリケーションによっては，小さなレコードのかたまりを繰り返し取得するかわりに，すべてのレコードを一度に取得することもできます。すべてのレコードの取得については，「レコードの取得」を参照してください。

4.	必要な変更がすべて終了するまでレコードのローカルコピーの表示と編集を続けます。

5.	ローカルにキャッシュした記録をデータベースに適用するか，更新を取り消します。データベースに書き込むどのレコードでも，OnUpdateRecord イベントが発生します。データベースに個々のレコードを書き込んでいるときにエラーが発生した場合は，OnUpdateError イベントが発生します。このイベントにより，アプリケーションは可能であればエラーを訂正し，更新を継続できます。更新が終了した場合，正しく適用された更新はすべてローカルキャッシュからクリアされます。データベースへの更新の適用については，「キャッシュアップデートの適用」を参照してください。

アプリケーションが更新を適用しないで取り消すと，ローカルにキャッシュしたレコードのコピーとそれらのコピーへのすべての変更はデータベースに書き込まれないで解放されます。更新の取り消しについては，「保留中のキャッシュアップデートの取り消し」を参照してください。


Enabling and disabling cached updates
Enabling and disabling cached updates1082004

Section topics	参照

キャッシュアップデートを使用可能または使用不可にするには，TTable，TQuery，TStoredProc の CachedUpdates プロパティを使います。デフォルトでは CachedUpdates は False で，データセットのキャッシュアップデートは使用不可になります。

キャッシュアップデートを使うには，設計時（オブジェクトインスペクタによる）または実行時に CachedUpdates を True に設定します。CachedUpdates を True に設定した場合，データセットの OnUpdateRecord イベントが用意されていれば OnUpdateRecord イベントが発生します。OnUpdateRecord イベントについては，「OnUpdateRecord イベントハンドラの作成」を参照してください。

たとえば次のコードは，実行時にデータセットのキャッシュアップデートを使用可能にします。

CustomersTable.CachedUpdates := True;

キャッシュアップデートを使用可能にすると，表示と編集に必要なすべてのレコードのコピーがローカルメモリにキャッシュされます。ユーザーはデータのこのローカルコピーを表示し，編集します。変更，挿入，削除もメモリにキャッシュされます。これらの操作は，ローカルな変更を含む現在のキャッシュをデータベースに適用するまでメモリに蓄積されます。変更したレコードがデータベースに正しく適用されると，これらの変更のレコードがキャッシュから解放されます。

メモ	キャッシュアップデートを適用しても，それ以後のキャッシュアップデートが使用不可になるわけではありません。キャッシュアップデートを適用すると，変更の現在の集合がデータベースに書き込まれ，それらの変更がメモリからクリアされるだけです。

データセットのキャッシュアップデートを使用不可にするには，CachedUpdates を False に設定します。まだ適用していない保留中の変更があるときにキャッシュアップデートを使用不可にすると，それらの変更は通知なしに破棄されます。アプリケーションではキャッシュアップデートを使用不可にする前に，この条件に該当しないか UpdatesPending プロパティをテストができます。たとえば次のコードは，データセットのキャッシュアップデートを使用不可にする前に確認を求めます。

if (CustomersTable.UpdatesPending) then

if MessageDlg('Discard pending updates?', mtConfirmation, mbYesNoCanel, 0) = mbOK then

CustomersTable.CachedUpdates := False;


Fetching records
Fetching records1082005

Section topics	参照

デフォルトでは，キャッシュアップデートを使用可能にした場合，Delphi は必要であればデータベースからのデータの取得を自動的に処理します。Delphi は表示に必要なだけのレコードを取得します。処理の過程では，このようなレコード取得が繰り返し行われることがあります。アプリケーションで特に必要な場合は，データセットの FetchAll メソッドを呼び出すと一度にすべてのレコードを取得できます。FetchAll はデータセットから読み出したすべてのレコードのローカルコピーをメモリ内に作成します。データセット内に多数のレコードまたは大きい BLOB 項目を持つレコードがある場合は，FetchAll を使わない方がよいでしょう。


Applying cached updates
Applying cached updates1082006

Section topics	参照

データセットがキャッシュアップデートモードの場合，データの変更はアプリケーションがそれらの変更を適用するメソッドを明示的に呼び出すまで，実際にデータベースに書き込まれることはありません。通常，アプリケーションはボタンやメニュー項目などによるユーザーの入力に応答して更新を行います。

重要	結果セットを返さない SQL の問い合わせで取り出したレコードの集合に更新を適用するには，TUpdateSQL オブジェクトを使って更新の実行方法を指定しなければなりません。結合（複数のテーブルが関係する問い合わせ）を更新する場合は，関係するテーブルごとにTUpdateSQL オブジェクトを 1 つ ずつ準備し，OnUpdateRecord イベントハンドラを使ってこれらのオブジェクトを呼び出して，更新を行わなければなりません。TUpdateSQL オブジェクトの作成と使い方については，「更新オブジェクトを使ったデータセットの更新」を参照してください。OnUpdateRecord イベントハンドラの作成と使い方については，「OnUpdateRecord イベントハンドラの作成」を参照してください。

アプリケーションがエラーから回復できるように，データベースのトランザクション処理の管理下で以下の 2 段階の処理が行われます。データベースコンポーネントによるトランザクション処理については，「データベースへの接続」を参照してください。

トランザクション制御の下で更新を行った場合，以下の処理が行われます。

1.	データベーストランザクションを開始する。

2.	キャッシュされている更新レコードがデータベースに書き込まれる（第 1 段階）。 OnUpdateRecord イベントが用意されていれば，データベースに書き込むレコードごとに 1 回ずつ OnUpdateRecord イベントが発生します。レコードをデータベースに適用するときにエラーが発生した場合は，OnUpdateError イベントが用意されていれば OnUpdateError イベントが発生します。OnUpdateRecord イベントについては，「OnUpdateRecord イベントハンドラの作成」を参照してください。

データベースの書き込みに失敗すると，以下の段階に移行します。

データベースの変更がロールバックされ，データベーストランザクションが終了する

キャッシュアップデートはコミットされず，そのまま内部キャッシュバッファに残る

データベースの書き込みに成功すると，以下の段階に移行します。

データベースの変更がコミットされ，データベーストランザクションが終了する

キャッシュアップデートがコミットされ，内部キャッシュバッファがクリアされる（第 2 段階）

たとえば，マスターリンクフォームでのデータセットなど，複数のデータセットを更新する場合のエラーからの回復が容易に行えます。キャッシュアップデートの適用時に発生する更新エラーの処理については，「キャッシュアップデートエラーの処理」を参照してください。

更新を適用するには，2 通りの方法があります。あるデータベースコンポーネントに関連するデータセットの指定された集合に更新を適用するには，そのデータベースコンポーネントの ApplyUpdates メソッドを呼び出すことができます。単一データセットに更新を適用するには，そのデータセットの ApplyUpdates メソッドと Commit メソッドを呼び出すことができます。これらの選択とその効果については，以降の各節で説明します。


Applying cached updates with a database component method
Applying cached updates with a database component method1082007

Section topics	参照

キャッシュアップデートをデータベース接続のコンテキストで 1 つまたは複数のデータセットに適用するには，そのデータベースコンポーネントの ApplyUpdates メソッドを呼び出します。次のコードは，ボタンクリックイベントに応答して CustomersQuery データセットの更新を適用します。

procedure ApplyButtonClick(Sender: TObject);

begin

if not IsSQLBased and (TransIsolation <> tiDirtyRead) then {Paradox, dBASE, FoxPro? }

TransIsolation := tiDirtyRead;
{ 該当する場合は TransIsolation を tiDirtyRead に設定する }

Database1.ApplyUpdates([CustomersQuery]);

end;

このメソッドはトランザクションを開始して，キャッシュアップデートをデータベースに書き込みます。成功した場合，トランザクションのコミット，さらにキャッシュアップデートのコミットが続きます。失敗した場合，このメソッドはトランザクションをロールバックし，キャッシュアップデートの状態をそのままにします。後者の場合は，アプリケーションがデータセットの OnUpdateError イベントを通じてキャッシュアップデートエラーを処理しなければなりません。キャッシュアップデートエラーの処理については，「キャッシュアップデートエラーの処理」を参照してください。

データベースコンポーネントの ApplyUpdates メソッドを呼び出すことの主な利点は，そのデータベースに関連するデータセットコンポーネントをいくつでも更新できることです。データベースの ApplyUpdates メソッドに渡す唯一の引数は，データセット名の配列です。複数のデータセットに更新を適用する場合は，データセット名をカンマで区切ります。たとえば次のコードは，マスターリンクフォームで使われる 2 つのテーブルに更新を適用します。

if not IsSQLBased and (TransIsolation <> tiDirtyRead) then {Paradox, dBASE, FoxPro? }

TransIsolation := tiDirtyRead;	{ 該当する場合は TransIsolation を tiDirtyRead に設定する }

Database1.ApplyUpdates([MasterTable, DetailTable]);

マスターリンクテーブルの更新については，「マスターリンクテーブルへの更新の適用」を参照してください。


Applying cached updates with dataset component methods
Applying cached updates with dataset component methods1082008

Section topics	参照

個々のデータセットについての更新は，そのデータセットの ApplyUpdates メソッドと CommitUpdates メソッドを使って，直接適用できます。これらのメソッドはどちらも更新プロセスの 1 つの段階をカプセル化します。

1.	ApplyUpdates はキャッシュにある変更をデータベースに書き込む（第 1 段階）。

2.	CommitUpdates はデータベースの書き込みに成功した場合，内部キャッシュをクリアする（第 2 段階）。

データセットレベルで更新を適用すると，個々のデータセットに更新を適用する順序を制御できます。更新の適用順序は，マスターリンク関係を処理する場合は特に重要です。マスターリンクテーブルの更新を正しい順序で行うには，常にデータセットレベルで更新を適用しなければなりません。詳細については，「データセットコンポーネントメソッドによるキャッシュアップデートの適用」および「マスターリンクテーブルへの更新の適用」を参照してください。

データセットのキャッシュアップデートメソッドを直接呼び出す場合は，その更新はデータベーストランザクションの制御下で適用されます。直前の CustomerQuery に対する例は，次のコードのように書くことができます。

procedure ApplyButtonClick(Sender: TObject);

begin

with CustomerQuery do

begin

Database1.StartTransaction;

try

if not IsSQLBased and (TransIsolation <> tiDirtyRead) then {Paradox, dBASE, FoxPro? }

TransIsolation := tiDirtyRead;	{ 該当する場合は TransIsolation を tiDirtyRead に設定する }

ApplyUpdates; { 更新されたレコードをデータベースに書き込もうとする }

Database1.Commit; { 成功した場合，変更をコミットする }

except

Database1.Rollback; { 失敗した場合，変更を取り消す }

raise; { CommitUpdates の呼び出しを防止するために再度例外を生成する }

end;

CommitUpdates; { 成功した場合，内部キャッシュをクリアする }

end;

end;

ApplyUpdates の呼び出し中に例外が生成された場合，データベーストランザクションはロールバックされます。トランザクションのロールバックでは，基礎になるデータベーステーブルは変更されません。例外ブロック内部の raise 文は例外を再生成するので，CommitUpdates の呼び出しは防止されます。CommitUpdates が呼び出されないため，エラー条件の処理と可能であれば更新の再試行ができるように更新の内部キャッシュはクリアされません。


Applying updates for master/detail tables
Applying updates for master/detail tables1082009

Section topics	参照

マスターリンクテーブルに更新を適用する場合は，更新するデータセットの順序が重要です。必ずリンクテーブルより先にマスターテーブルを更新してください。ある関係のリンクテーブルがほかのリンクテーブルのマスターテーブルであるような複雑なマスターリンク関係の場合も同じ規則が適用されます。

マスターリンクテーブルの更新は，データベースコンポーネントレベルででもデータセットコンポーネントレベルででもできます。制御のために，また自分で記述したコードを明示的に作成するために，データセットレベルで更新を適用するのがよいでしょう。次の例は，マスターリンク関係にある 2 つのテーブルに対するキャッシュアップデートのコードの作成方法を示しています。

Database1.StartTransaction;

try

Master.ApplyUpdates;

Detail.ApplyUpdates;

Database1.Commit;

except

Database1.Rollback;

raise;

end;

Master.CommitUpdates;

Detail.CommitUpdates;

更新の適用中にエラーが発生した場合，このコードはキャッシュと元データベーステーブルのデータの両方を ApplyUpdates の呼び出し前の状態のままに戻します。

Master.ApplyUpdates の呼び出し中に例外が生成された場合，その例外は前述の単一データセットの場合と同様に処理されます。ただし，Master.ApplyUpdates の呼び出しが成功し，次の Detail.ApplyUpdates の呼び出しに失敗した場合，変更はすでにマスターテーブルに適用されています。しかしながら，すべてのデータがデータベーストランザクション内部で更新されるため，マスターテーブルに対する変更でさえも，例外ブロックで Database1.Rollback が呼び出されたときにロールバックされます。さらに，raise により例外が再生成されるので Master.CommitUpdates がスキップされ呼び出されず，したがってキャッシュも更新の試行前の状態に保たれます。

2 段階更新プロセスの価値を評価するために，ApplyUpdates がデータおよびキャッシュを一度にまとめて処理するものと仮定してみます。その場合，リンクテーブルへ更新を適用している間にエラーが発生すると，データとキャッシュの両方を元の状態に戻す方法はまったくないことになります。Database.Rollback の呼び出しによりデータベースを復元できても，キャッシュを復元する方法はありません。

メモ	この節で示した例では，データセットの ApplyUpdates と CommitUpdates を別々に呼んでいますが，TDatabase コンポーネントの ApplyUpdates メソッドが行っている処理と同じものです。


Canceling pending cached updates
Canceling pending cached updates1082010

Section topics	参照

保留中のキャッシュアップデートとは，キャッシュに登録されていてまだデータベースに適用されていない更新レコードです。保留中のキャッシュアップデートを取り消すには，次の 3 通りの方法があります。

すべての保留中の更新を取り消し，それ以後のキャッシュアップデートを使用不可にするには，CachedUpdates プロパティを False に設定する

それ以後のキャッシュアップデートを使用不可にしないですべての保留中の更新を破棄するには，CancelUpdates メソッドを呼び出す

現在のレコードに加えた更新を取り消すには，RevertRecord を呼び出す。

これらの操作については，以降の各節で詳細に説明します。


Cancelling pending updates and disabling further cached updates
Cancelling pending updates and disabling further cached updates1082011

Section topics	参照

すべての保留中のキャッシュアップデートを適用しないで削除し，それ以後の更新のキャッシュを取り消すには，CachedUpdates プロパティを False に設定します。CachedUpdates を False に設定すると，CancelUpdates メソッドが自動的に呼び出されます。


Canceling pending cached updates
Canceling pending cached updates1082012

Section topics	参照

CancelUpdates はキャッシュをクリアして，テーブルが開いたとき，キャッシュアップデートが使用可能になったとき，あるいは更新の適用が最後に成功したときの状態にデータセットを戻します。たとえば，次の文は CustomersTable の更新を取り消します。

CustomersTable.CancelUpdates;

メモ	CancelUpdates を呼び出しても，キャッシュアップデートは使用不可になりません。CancelUpdates は現在保留中の更新を取り消すだけです。それ以後のキャッシュアップデートを使用不可にするには，CachedUpdates プロパティを False に設定してください。


Canceling updates to the current record
Canceling updates to the current record1082013

Section topics	参照

RevertRecord はデータセットの現在のレコードを，テーブルが開いたとき，キャッシュアップデートが最後に使用可能だったとき，または更新が最後に正しく適用されたときの状態に戻します。RevertRecord は，エラー状態を修正するためにOnUpdateError イベントハンドラでもっともよく使われます。たとえば，次のようにします。

CustomersTable.RevertRecord;

レコードが変更されていない場合，RevertRecord を呼び出しても何も効果はありません。OnUpdateError ハンドラの作成については，「キャッシュアップデートエラーの処理」を参照してください。


Undeleting a cached record
Undeleting a cached record1082014

Section topics	参照

いったん削除したレコードはキャッシュに登録されて現在のレコードでなくなるので，キャッシュレコードの削除を取り消すにはなんらかのコードが必要です。しかし，ときにはそのようなレコードの削除を取り消したいことがあります。このプロセスでは，UpdateRecordTypes プロパティを使って削除レコードを「見える」状態にしてから RevertRecord を呼び出します。次に示すコードの例は，テーブルにあるすべての削除レコードの削除を取り消します。

procedure UndeleteAll(DataSet: TDataSet);

begin

with DataSet do

begin

UpdateRecordTypes := [rtDeleted];

try

First;

 while not EOF do

RevertRecord;

finally

UpdateRecordTypes := [rtModified, rtInserted, rtUnmodified];

end;

end;

end;


Specifying visible records in the cache
Specifying visible records in the cache1082015

Section topics	参照

UpdateRecordTypes プロパティは，キャッシュアップデートが使用可能なときにキャッシュ内のどの種類のレコードを見えるようにするかを制御します。UpdateRecordTypes によるキャッシュレコードの操作方法は，フィルタによるテーブルの操作方法とほぼ同じです。UpdateRecordTypes は集合なので，次の値の任意の組み合わせを含むことができます。

値	意味
rtModified	変更されたレコード
rtInserted	挿入レコード
rtDeleted	削除レコード
rtUnmodified	変更されていないレコード
UpdateRecordTypes のデフォルト値は [rtModified, rtInserted, rtUnmodified] です。

UpdateRecordTypes プロパティは，OnUpdateError イベントハンドラで，RevertRecord の呼び出しを通じて削除を取り消せるようにするために削除レコードにアクセスする場合に主に役立ちます。このプロパティは，キャッシュレコードのサブセット，たとえばすべての新規挿入（rtInserted）レコードだけをユーザーに見せるようにアプリケーションで対処する場合にも役立ちます。OnUpdateError ハンドラの作成については，「キャッシュアップデートエラーの処理」を参照してください。


Checking update status
Checking update status1082016

Section topics	参照

キャッシュアップデートがアプリケーションで使用可能な場合，キャッシュ内の保留中の各更新レコードについて UpdateStatus プロパティを調べると，そのレコードの状態を把握できます。更新状態のチェックは，イベントハンドラの OnUpdateRecord と OnUpdateError でもっともよく使われます。OnUpdateRecord イベントの作成と使い方については，「OnUpdateRecord イベントハンドラの作成」を参照してください。OnUpdateError イベントの作成と使い方については，「キャッシュアップデートエラーの処理」を参照してください。

保留中の変更の集合を繰り返し処理するとき，UpdateStatus は現在のレコードの更新状態を反映して変化します。UpdateStatus からは，現在のレコードについて以下のいずれかの値が返されます。

値	意味
usUnmodified	変更されていないレコードである
usModified	変更されたレコードである
usInserted	新規レコードである
unDeleted	削除されたレコードである
データセットが最初に開いたとき，すべてのレコードの更新状態は usUnmodified になります。レコードの挿入や削除などがあると，状態の値が変わります。次に示す例は，OnCalcFields イベントハンドラで UpdateStatus プロパティを使って，計算項目の関連するレコードが変更された場合にその計算項目にアスタリスク（*）を表示する例です。

procedure TForm.CalcFields(DataSet: TDataSet);

begin

if DataSet.UpdateStatus <> usUnmodified then

Table1ModifiedRow.Value := '*'

else

Table1ModifiedRow.Value := Null;

end;

メモ	レコードの UpdateStatus が usModified の場合は，データセットの各項目の OldValue プロパティを調べれば，変更前の値がわかります。OldValue は UpdateStatus の値が usModified 以外のレコードでは意味がありません。OldValue の検査と使い方については，「OldValue と NewValue へのアクセス」を参照してください。


Determining if you need to control the updating process
Determining if you need to control the updating process1082017

Section topics	参照

キャッシュアップデートを使うときには，ApplyUpdates を呼び出すだけでキャッシュした変更をデータベースに書き込めることがあります。たとえば，TTable コンポーネントを通してローカルな Paradox または dBASE のテーブルへの排他的アクセス権を持っている場合などです。しかし，それ以外のほとんどの場合は，更新を適用できるようにする処理の追加が必要になります。

たとえば，データをテーブルに適用する前に OnUpdateRecord イベントを使ってデータ調整用の検証ルーチンを呼び出したいことがあります。また，マスターテーブルとリンクテーブルのレコードをデータベースに書き込む前に，OnUpdateRecord イベントを使ってそれらのレコードに追加処理を行いたことがあります。

多くの場合，追加処理が必要です。たとえば，キャッシュアップデートを使用可能にし，結果セットを返さない TQuery コンポーネントを使ってデータにアクセスする場合にはいつでも，SQL 文またはレコードの更新に必要な文を提供する TUpdateSQL オブジェクトを与えなければなりません。さらに，結合した問い合わせを使って複数のテーブルにアクセスする場合は，問い合わせのテーブルごとに TUpdateSQL オブジェクトを 1 つずつ与えるとともに，データベースへの変更の書き込みにそれぞれの更新オブジェクトが使われるようにするために OnUpdateRecord イベントを使わなければなりません。

TUpdateSQL オブジェクトの作成方法と使い方，および OnUpdateRecord イベントの作成方法と使い方については，以降の各節で説明します。


Using update objects to update a dataset
Using update objects to update a dataset1082018

Section topics	参照

TUpdateSQL は，SQL 文を使ってデータセットを更新するコンポーネントです。元の問い合わせでアクセスされる更新対象のテーブルごとに TUpdateSQL コンポーネントを 1 つずつ与えなければなりません。

メモ	更新操作のために複数の TUpdateSQL コンポーネントを使う場合には， OnUpdateRecord イベントの中でそれぞれの TUpdateSQL コンポーネントを適切に呼び出さなければなりません。

TUpdateSQL コンポーネントは，実際には 3 つの TQuery コンポーネントをカプセル化しています。各問い合わせコンポーネントはそれぞれが単一の更新処理を実行します。1 つ目の問い合わせコンポーネントが既存のレコード変更用の SQL 文 UPDATE を提供し，2 つ目がテーブルへの新規レコード追加用の INSERT 文を提供します。3 つ目の問い合わせコンポーネントがテーブルからのレコード削除用の DELETE 文を提供します。

データモジュールにアップデートコンポーネントを追加する場合，カプセル化された TQuery コンポーネントは見えません。それらの問い合わせコンポーネントは，設計時に指定した以下の 3 つの更新プロパティに基づき，実行時に TUpdateSQL コンポーネントによって作成されます。

ModifySQL は UPDATE 文を指定する

InsertSQL は INSERT 文を指定する

DeleteSQL は DELETE 文を指定する

実行時に TUpdateSQL コンポーネントを使って更新を行うと，TUpdateSQL コンポーネントは以下の処理を行います。

1.	TUpdateSQL コンポーネントが属している先のデータセットの UpdateKind パラメータに基づき実行する SQL 文を選択します。UpdateKind は現在のレコードが変更レコード，挿入レコード，削除レコードのいずれであるかを指定します。

2.	パラメータ値を SQL 文に渡します。

3.	指定された更新を実行する SQL 文を用意して実行します。


Specifying the UpdateObject property for a dataset
Specifying the UpdateObject property for a dataset1082019

Section topics	参照

データセットコンポーネントの UpdateObject プロパティは，TUpdateObject 型のアップデートオブジェクトコンポーネントへのオプションの参照です。読み出し専用データセットで ApplyUpdates を呼び出した場合，UpdateObjectプロパティが設定されていると，そのアップデートオブジェクトコンポーネントは更新を必要とする各レコードごとに呼び出されます。TUpdateObject コンポーネントの操作については，「TUpdateSQL コンポーネントの SQL プロパティの使い方」を参照してください。

データセットコンポーネントの UpdateObject プロパティは 1 つだけですが，更新の使える TUpdateObject コンポーネントの数に制限はありません。複数の TUpdateObject コンポーネントが必要な場合は，そのデータセットコンポーネントの OnUpdateRecord イベントハンドラを使って追加の TUpdateObject コンポーネントを呼び出します。OnUpdateRecord については，「OnUpdateRecord イベントハンドラの作成」を参照してください。


Creating SQL statements for update components
Creating SQL statements for update components1082020

Section topics	参照

TUpdateSQL コンポーネントの SQL 文を作成する手順は次のとおりです。

1.	コンポーネントパレットの［Data Access］ページにある TUpdateSQL コンポーネントをデータモジュールまたはフォームに配置します。

2.	TUpdateSQL コンポーネントをデータセットの UpdateObject パラメータでデータセットに割り当てます。この手順は，次の手順で呼び出す SQL 更新エディタが，SQL 生成オプションに使う適切なデフォルト値を決められるようにします。

3.	TUpdateSQL コンポーネントをダブルクリックして SQL 更新エディタを呼び出します。このエディタは，基礎になるデータセットとそれに指定した値とに基づき，その TUpdateSQL コンポーネントの ModifySQL，InsertSQL，DeleteSQL の各プロパティ用に SQL 文を作成します。

SQL 更新エディタは 2 つのページで構成されています。［オプション］ページは，このエディタを最初に呼び出したときに表示されるページです。［テーブル名(N)］コンボボックスは，更新するテーブルを選択するために使います。テーブル名を指定すると，［キー項目(K)］リストボックスと［更新する項目(F)］リストボックスに，使用可能な列のリストが表示されます。

［更新する項目(F)］リストボックスは，どの列が更新対象であるかを示します。最初にテーブルを指定したときは，［更新する項目(F)］リストボックスのすべての列が選択されて含まれています。希望する項目を複数選択できます。

［キー項目(K)］リストボックスは，更新中にキーとして使う列を指定するのに使います。 Paradox，dBASE，FoxPro の場合，ここに指定する列は既存のインデックスに対応していなければなりませんが，リモート SQL データベースの場合はその必要はありません。［キー項目(K)］で設定を行うかわりに，［主インデックスを選択(P)］ボックスをクリックしてデータセットの一次インデックスを選択することもできます。

サーバーが項目名を引用符で囲むように要求している場合は，［項目名を"で括る(Q)］チェックボックスにチェックマークを付けます。［主インデックスを選択(P)］をクリックして，テーブルの一次インデックスに基づくキー項目を選択します。

テーブルを指定してキー列と更新列を選択した後は，［SQL 文を生成(G)］をクリックして TUpdateSQL コンポーネントの ModifySQL，InsertSQL，DeleteSQL の各プロパティに関連付ける予備の SQL 文を生成します。ほとんどの場合，Delphi が生成した SQL 文の微調整が必要になります。

生成した SQL 文を表示して変更するには，必要に応じて［SQL］ページを選択します。SQL 文を生成してこのページを選択した場合，ModifySQL プロパティの文が［SQL 文(Q)］メモボックスにすでに表示されています。このボックス内の文を希望どおりに編集できます。

重要	生成した SQL 文は更新文の作成用の土台であることに注意してください。正しく実行させるには変更する必要があるかもしれません。それぞれの文を受け入れる前に直接自分でテストしてください。

［SQL 文の種類］ラジオボタンは，生成した SQL 文の種類を切り替えて各文を編集するために使います。

文を TUpdateSQL コンポーネントの SQL プロパティと関連付けるには，［OK］をクリックします。

Handling updates to existing records1082021

既存のレコードを更新するには，更新オブジェクトの ModifySQL プロパティを使って，更新操作を実行する SQL UPDATE 文を指定します。また，更新オブジェクトの親データセットの UpdateModeプロパティも必ず適切な値に設定してください。UpdateMode は，Delphi が更新レコードをどのように見つけるかを指定します。表に UpdateMode で可能な値を示します。

値	意味
upWhereAll	デフォルト。すべての項目が UPDATE 文の WHERE 節に指定されている値と厳密に一致するレコードだけを更新する。もっとも制約の厳しい更新モード
upWhereKeyOnly	指定されたキー列に基づいてレコードを更新する。もっとも制約の緩いモードなので，アプリケーションがデータに排他的アクセス権を持っている場合にだけ使う
upWhereChange	キー列と変更された列に基づいてレコードを更新する
Understanding parameter substitution in generated SQL statements1082022

生成した SQL 更新文は特殊な形式のパラメータ置換を使います。この置換では，レコードの更新で古い項目値と新しい項目値のどちらをかわりに使うかを決めることができます。SQL 更新エディタはその文を生成するときに，どの項目値を使うかを決めます。

パラメータ名がテーブル内の列名と一致した場合は，新しい値が使われます。パラメータ名が文字列 OLD_ が前に付く列名と一致した場合は，古い値が使われます。

新しい項目値は通常，InsertSQL 文や ModifySQL 文の中で使われます。削除レコードの場合は新しい値はないので，DeleteSQL プロパティが :Old_FieldName 構文を使います。古い項目値は通常，更新対象のレコードを決めるために SQL 文の WHERE 節の中でも使われます。

新旧の値パラメータの置換についての詳細は，「OldValue と NewValue へのアクセス」を参照してください。


Using an update component's DataSet property
Using an update component's DataSet property1082023

Section topics	参照

TUpdateSQL コンポーネントの DataSet プロパティは更新するデータセットを識別します。通常，このプロパティは TUpdateSQL コンポーネントを使うデータセットの名前に基づいて自動的に設定されます。ただし，複数の TUpdateSQL コンポーネントを使ってデータセットを更新する場合は，実行時にこの値を与えなければなりません。


Accessing an update component's Query property
Accessing an update component's Query property1082024

Section topics	参照

TUpdateSQL コンポーネントの Query プロパティは，更新を行う TUpdateSQL コンポーネントで呼び出される TQuery コンポーネントへのアクセスを提供します。ほとんどの場合，このプロパティにアクセスする必要はありませんが，アクセスする必要がある場合は，UpdateKind パラメータ値を問い合わせコンポーネントの配列へのインデックスとして使うことができます。

メモ	Query は UpdateObject のプロパティではありません。データセットからそのプロパティを参照する場合は，UpdateObject プロパティを型キャストする必要があります。次に例を示します。

(DataSet.UpdateObject as TUpdateSQL).Query[UpdateKind];

このプロパティの使い方の例については，「SetParams メソッドの呼び出し」を参照してください。


Using an update component's SQL property
Using an update component's SQL property1082025

Section topics	参照

実行時に TUpdateSQL コンポーネントの SQL プロパティは，その ModifySQL，InsertSQL，DeleteSQL の各プロパティへアクセスするインデックス付きのメソッドを提供します。UpdateKind の値をインデックスとして使います。次に例を示します。

SQL[ukModify] = ModifySQL

通常，SQL プロパティによってインデックス付けされたプロパティは設計時に SQL 更新エディタを使って設定されます。ただし，レコードごとにユニークな SQL 更新文を生成しており，パラメータ割り当てを使っていない場合は，実行時にプロパティの設定値にアクセスする必要があります。次のコードは，更新された行ごとにユニークな SQL プロパティ値を生成します。

procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

with DataSet.UpdateObject do

begin

case UpdateKind of

ukModified:

begin

SQL[UpdateKind].Text := Format('update emptab set Salary = %d where EmpNo = %d',

[EmpAuditSalary.NewValue, EmpAuditEmpNo.OldValue]);

ExecSQL(UpdateKind);

end;

ukInserted:

{...}

ukDeleted:

{...}

end;

end;

UpdateAction := uaApplied;

end;

メモ	独自の SQL 文を構築する前に，TUpdateSQL コンポーネントによって与えられるパラメータ置換を利用するようにして下さい。


Calling the Apply method
Calling the Apply method1082026

Section topics	参照

TUpdateSQL コンポーネントの Apply メソッドはその時点での変更を反映します。このプロセスには次の 2 つの手順が関係します。

1.	レコードの値を適切な SQL 文のパラメータに割り当てます。

2.	SQL 文を実行します。

このメソッドは，関連するデータセットによって自動的に呼び出されるか，OnUpdateRecord イベントから明示的に呼び出されるかのどちらかです。UpdateKind パラメータは，どの SQL 更新文を使うかを決めるために使います。関連するデータセットによって呼び出される場合，UpdateKind は自動的に設定されます。このメソッドを OnUpdateRecord イベントで呼び出す場合は，そのイベントの UpdateKind パラメータを Apply に渡します。

更新プログラムの実行中に例外が生成された場合は，定義されていれば，OnUpdateError イベントで実行が継続します。

メモ	Apply で実行される操作は，次の 2 つの節で説明される SetParams メソッドと ExecSQL メソッドに対応します。


Calling the SetParams method
Calling the SetParams method1082027

Section topics	参照

TUpdateSQL コンポーネントの SetParams メソッドは特殊なパラメータ置換規則を使って古い項目値または新しい項目値で置換して SQL 更新文に入れます。通常，SetParams は TUpdateSQL コンポーネントの Apply メソッドによって自動的に呼び出されます。Apply を OnUpdateRecord イベントで直接呼び出す場合は，SetParams を自分で呼び出すことはしないでください。

SetParams はどの SQL 文がパラメータを設定するかを UpdateKind パラメータを調べて決めます。

パラメータ割り当てによる特殊な制御が必要な場合は，SetParams を直接呼び出すだけですみます。次の例はそのような使い方の例を示しています。

procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

with DataSet.UpdateObject as TUpdateSQL do

begin

SetParams(UpdateKind);

if UpdateKind = ukModified then

Query[UpdateKind].ParamByName('DateChanged').Value := Now;

ExecSQL(UpdateKind);

end;

UpdateAction := uaApplied;

end;

メモ	この例は，TUpdateSQL コンポーネントの ModifySQL プロパティが次のとおりであると想定しています。

UPDATE EMPAUDIT

SET EmpNo = :EmpNo, Salary = :Salary, Changed = :DateChanged

WHERE EmpNo = :OLD_EmpNo

この例では，SetParams の呼び出しで EmpNo パラメータと Salary パラメータに値を与えています。DateChanged パラメータが設定されないのは，名前がデータセット中の項目の名前と一致していないためで，したがって次のコード行がこの値を明示的に設定しています。


ExecSQL
ExecSQL1082028

Section topics	参照

TUpdateSQL コンポーネントの ExecSQL メソッドは準備済みの SQL 更新文を実行します。通常，ExecSQL は TUpdateSQL コンポーネントの Apply メソッドによって自動的に呼び出されます。Apply を OnUpdateRecord イベントで直接呼び出す場合は，ExecSQL を自分で呼び出すことはしないでください。

ExecSQL はどの SQL 文をレコードの UpdateKind パラメータに基づいて実行するかを決めます。

SQL 更新文の実行中に例外が生成された場合は，OnUpdateError イベントが発生します。


Executing UpdateSQL statements
Executing UpdateSQL statements1082029

Section topics	参照

データベースコンポーネントまたはデータセットコンポーネントの ApplyUpdates メソッドを呼び出した場合，データセットの UpdateObject プロパティによって TUpdateSQL コンポーネントがデータセットに関連付けられていれば，その TUpdateSQL コンポーネントに関連付けられている更新文が自動的に実行されます。

データセットで更新を実行するために複数の TUpdateSQL コンポーネントを使う場合，更新文は自動的には実行されません。その場合や，ApplyUpdates で追加の処理を実行したい場合は，OnUpdateRecord イベントハンドラを作成して，使われる各 TUpdateSQL コンポーネントに関連付けられた更新文を実行しなければなりません。


Updating a read-only result set
Updating a read-only result set1082030

Section topics	参照

データセットコンポーネントの RequestLive プロパティが True の場合，BDE は常時更新可能な，つまり「ライブ」問い合わせ結果を提供しようとしますが，それができない状況もあります。そのようなときにデータセットを手作業で更新する手順は次のとおりです。

1.	TUpdateSQL コンポーネントをアプリケーション内のデータモジュールに追加します。

2.	データセットコンポーネントの UpdateObject プロパティをデータモジュールの TUpdateSQL コンポーネントの名前に設定します。

3.	結果セットの SQL 更新文を TUpdateSQL コンポーネントの ModifySQL，InsertSQL，DeleteSQL のいずれかのプロパティに入力するか，SQL 更新エディタを使います。

4.	データセットを閉じます。

5.	データセットコンポーネントの CachedUpdates プロパティを True に設定します。

6.	データセットを再度開きます。

メモ	多くの場合，データセットには OnUpdateRecord イベントハンドラも必要になります。


Creating an OnUpdateRecord event handler
Creating an OnUpdateRecord event handler1082031

Section topics	参照

OnUpdateRecord イベントハンドラは，単一の TUpdateSQL コンポーネントで必要な更新を実行できない場合や，アプリケーションで特殊なパラメータ置換の制御がさらに必要な場合などを処理します。

DataSet.UpdateObject.Apply(UpdateKind);

データセットの OnUpdateRecord イベントハンドラを作成する手順は次のとおりです。

1.	データセットコンポーネントを選択します。

2.	オブジェクトインスペクタで［イベント］ページを選択します。

3.	OnUpdateRecord プロパティ値をダブルクリックしてコードエディタを呼び出します。

OnUpdateRecord イベントハンドラの概略コードを次に示します。

procedure TForm1.DataSetUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

{ ここで更新を行う }

end;

DataSet パラメータは更新するデータセットを示します。

UpdateKind パラメータは実行する更新の種類を示します。TUpdateSQL コンポーネントを使う場合は，このパラメータをアクセス対象のメソッドとプロパティに渡す必要があります。実行する更新の種類に基づいてハンドラが何か特殊な処理を実行する場合は，このパラメータを調べる必要もあります。

UpdateAction パラメータは更新を適用したかどうかを示します。デフォルト値は uaFail です。更新中に問題が発生しない限り，イベントハンドラは終了前にこの値を uaApplied に設定する必要があります。特定のレコードを更新しないことに決めた場合は，値を uaSkip に設定して未適用の変更をキャッシュに保持します。

UpdateAction の値を変更しない場合，そのデータセットの更新操作全体が中止されます。UpdateAction については，「実施する処理の指定」を参照してください。

これらのパラメータ以外に，現在のレコードに関連した項目コンポーネントの OldValue プロパティや NewValue プロパティを使用したいと考えるでしょう。OldValue と NewValue については，「OldValue と NewValue へのアクセス」を参照してください。

重要	イベントハンドラの OnUpdateError や OnCalcFields と同様に，OnUpdateRecord イベントは，データセット内の現在のレコードポインタを変更するようなメソッドを決して呼び出してはなりません。

OnUpdateRecord は通常，1 つまたは複数の TUpdateSQL コンポーネントを使ってデータセットを更新します。TUpdateSQL コンポーネントを使うことはデータセットを更新するもっとも簡単な方法ですが，必ずしもその方法を使う必要はありません。たとえば次のコードは，テーブルコンポーネントを使って更新を行います。

procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

if UpdateKind = ukInsert then

UpdateTable.AppendRecord([DataSet.Fields[0].NewValue, DataSet.Fields[1].NewValue])

else

if UpdateTable.Locate('KeyField', DataSet.Fields[0].OldValue, []) then

case UpdateKind of

ukModify:

begin

Edit;

UpdateTable.Fields[1].Value := DataSet.Fields[1].Value;

Post;

end;

ukModify: DeleteRecord;

end;

UpdateAction := uaApplied;

end;

通常は，OnUpdateRecord イベントハンドラは次のように複数の TUpdateSQL コンポーネントを使います。

procedure TForm1.EmpAuditUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

EmployeeUpdateSQL.Apply(UpdateKind);

JobUpdateSQL.Appply(UpdateKind);

UpdateAction := uaApplied;

end;

この例では DataSet パラメータが使われていません。これは，ハンドラで呼び出される TUpdateSQL コンポーネントがデータモジュールに属しており，UpdateObject プロパティを通しては参照されないためです。

重要	データセットの UpdateObject プロパティと OnUpdateObjectイベントハンドラの両方が指定されている場合には，UpdateObject プロパティが示しているアップデートオブジェクトは自動的には呼び出されません。OnUpdateObjectハンドラの中から Apply メソッドを使って明示的に呼んでください。


Handling cached update errors
Handling cached update errors1082032

Section topics	参照

レコードが最初にキャッシュに格納された時間とキャッシュアップデートが適用される時間にはずれがあるため，アプリケーションが更新を行う前に，ほかのアプリケーションがデータベース内の該当レコードを変更している可能性があります。ボーランドデータベースエンジン（BDE）は，更新を行おうとするときにこのような変更の有無を確実に調べ，変更があるとエラーを通知します。

データセットコンポーネントの OnUpdateError イベントを使うと，このようなエラーを（ほかの更新エラーも）捕えて応答することができます。キャッシュアップデートを使う場合は，このイベントハンドラを作成してください。作成しない場合にエラーが発生すると，更新操作全体が失敗に終わります。

注意	OnUpdateError イベントハンドラの中では，現在のレコードを変更するデータセットメソッド（Next や Prior など）は呼び出さないでください。呼び出すと，イベントハンドラが無限ループに入ります。

OnUpdateError イベントハンドラの概略コードを次に示します。

procedure TForm1.DataSetUpdateRecord(DataSet: TDataSet;

UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);

begin

{ ここで更新を行う }

end;

以降の各節では，更新エラーハンドラに渡される各パラメータについてと，それらのパラメータの使い方について説明します。


Referencing the dataset to which to apply updates
Referencing the dataset to which to apply updates1082033

Section topics	参照

DataSet は更新の適用先のデータセットへの参照が渡されます。エラー処理時に新しいレコード値と古いレコード値を処理するには，この値を参照します。


Indicating the type of update that generated an error
Indicating the type of update that generated an error1082034

Section topics	参照

UpdateKind は TUpdateKind 型のパラメータで，エラーを生成した更新の種類を示します。実行中の更新の種類に基づいてエラーハンドラで特別な処理を実行するのでなければ，コードでこのパラメータを使うことはないでしょう。

表に UpdateKind で可能な値を示します。

値	意味
ukModify	既存のレコードの編集でエラーになった
ukInsert	新規レコードの挿入でエラーになった
ukDelete	既存のレコードの削除でエラーになった


Specifying the action to take
Specifying the action to take1082035

Section topics	参照

UpdateAction は TUpdateAction 型のパラメータです。更新エラーハンドラを初めて呼び出した場合，このパラメータの値は必ず uaFail に設定されます。エラーを引き起こしたレコードのエラー条件とその修正のための措置に基づき，通常はハンドラの終了前に UpdateActionを別の値に設定します。UpdateAction は次の値のいずれかに設定できます。

値	意味
uaAbort	エラーメッセージの表示なしで更新操作を中止する
uaFail	更新操作を中止してエラーメッセージを表示する。これは，更新エラーハンドラに入る場合の UpdateAction のデフォルト値である
uaSkip	行の更新をスキップし，レコードの更新をキャッシュに残す
uaRetry	更新操作を繰り返す。UpdateAction をこの値に設定する前に，エラー条件を修正する
uaApplied	エラー処理ルーチンでは使われない
エラーハンドラの呼び出しの原因となったエラー条件をエラーハンドラで修正できる場合は，UpdateAction を終了時にとるべき適切な操作に設定します。エラー条件を修正できた場合は，UpdateAction を uaRetry に設定してそのレコードの更新を再度適用します。

uaSkip に設定すると，エラーを引き起こした行の更新はスキップされ，そのレコードの更新はほかのすべての更新が完了した後でキャッシュに残ります。

uaFail と uaAbort は似ています。両方とも更新操作全体を終了します。uaFail は例外を生成してエラーメッセージを表示します。uaAbort はサイレント例外を生成します（エラーメッセージを表示しません）。

メモ	更新の適用中にエラーが発生した場合は，ApplyUpdates メソッドが try...except 文の内部から呼び出されていない限り，ApplyUpdates の呼び出し後にエラーメッセージが表示されます。エラーイベントハンドラの内部からもユーザーにエラーメッセージを表示する場合は，アプリケーションが同じエラーメッセージを 2 回表示する可能性があります。エラーメッセージが繰り返されるのを防ぐには，UpdateAction を uaAbort に設定してエラーメッセージの表示をオフにします。

uaApplied 値は OnUpdateRecord イベント内だけで使うようにしてください。この値は更新エラーハンドラの中には設定しないでください。レコード更新イベントについては「OnUpdateRecord イベントハンドラの作成」を参照してください。


Working with error message text
Working with error message text1082036

Section topics	参照

E パラメータは通常 EDBEngineError 型です。この例外の型からは，ユーザーに表示できるエラーメッセージをエラーハンドラで抽出できます。たとえば次のコードは，ダイアログボックスのキャプションにエラーメッセージを表示するのに使えます。

ErrorLabel.Caption := E.Message;

このパラメータは，更新エラーの実際の原因を調べる場合にも役立ちます。EDBEngineError から特定のエラーコードを抽出し，それに基づいて適切な処理を実行できます。たとえば次のコードは，更新エラーがキー違反に関係するかどうかを調べ，関係する場合には UpdateAction パラメータを uaSkip に設定します。

{ この例では「Bde」を uses 節に追加する }

if E is EDBEngineError then

with EDBEngineError(E) do

begin

if Errors[ErrorCount - 1].ErrorCode = DBIERR_KEYVIOL then

UpdateAction := uaSkip	{ キー違反の場合，このレコードをスキップする }

else

UpdateAction := uaAbort	{ 原因不明の場合，更新を中止する }

end;


Accessing a field's OldValue and NewValue properties
Accessing a field's OldValue and NewValue properties1082037

Section topics	参照

キャッシュアップデートがレコードで使用可能な場合，各レコードの項目の元の値は OldValue という読み出し専用の TField プロパティに格納されます。変更された値は TField プロパティの NewValue に格納されます。これらの値は，イベントハンドラ OnUpdateError および OnUpdateRecord で更新値を調べたり変更するための唯一の方法になります。OnUpdateRecord については，「OnUpdateRecord イベントハンドラの作成」を参照してください。

場合によっては，これらのプロパティを使ってエラーの原因を特定し，そのエラーを修正できることがあります。たとえば次のコードは，（サーバー上で制限をかけているために）一度に最高 25% しか増加できない給与項目に対する修正を処理します。

var

SalaryDif: Integer;

OldSalary: Integer;

begin

OldSalary := EmpTabSalary.OldValue;

SalaryDif := EmpTabSalary.NewValue - OldSalary;

if SalaryDif / OldSalary > 0.25 then

begin

{ 増加が大きすぎるので，25% の増加に抑える }

EmpTabSalary.NewValue := OldSalary + OldSalary * 0.25;

UpdateAction := uaRetry;

end

else

UpdateAction := uaSkip;

end;

給与が 25% よりも大きく増えた場合には NewValue の値は 25% に抑えられ，更新操作が再試行されます。このルーチンの効率を向上させるために，OldValue パラメータをローカル変数に格納しています。


See also1082038

TStoredProc

TQuery

TTable

TDataSet

TDatabase

TUpdateSQL

データベースへの接続


Using data controls
Using data controls1083001

Section topics 	参照

この章では，データベース対応のビジュアルコントロールを使って，データベースアプリケーションのテーブルや問い合わせに関連付けられたデータを表示／編集する方法について説明します。データベース対応コントロールは，アプリケーション外部のデータベースソースから表示データを取得し，さらにデータの変更をデータソースに登録することも，登録せずに元に戻すこともできます。

この章では，すべてのデータコントロールコンポーネントに共通の基本機能について説明してから，個々のコンポーネントを使う方法とタイミングについて説明します。

この章では特に，データコントロールに共通の以下の機能について説明します。

データセットへのデータコントロールの関連付け

データの編集と更新

データ表示の無効化と有効化

データ表示の更新

ナビゲータコントロールである TDBNavigator（ユーザーにレコード間の移動とレコードの編集用のビジュアルツールを提供するコントロール）を含めて，ほとんどのデータコントロールについての説明がこの章にあります。

データベース対応コントロールのいくつかの特殊なものとさらに複雑なものについては，以降の各章で説明します。グリッドコントロールの TDBGrid と TDBCtrlGrid については「グリッドの操作」を参照してください。テシジョンキーブのグリッドコントロールとグラフコントロールについては「テシジョンキーブコンポーネントの使い方」を参照してください。


Using common data control features
Using common data control features1083002

Section topics 	参照

コンポーネントパレットの［Data Controls］ページにあるデータコントロールをデータベースアプリケーションのフォームに配置します。通常，データコントロールを使うと，データセットの現在のレコードに関連付けられたデータの項目の表示と編集ができます。表にコンポーネントパレットの［Data Controls］ページにあるデータコントロールの概要を示します。

データコントロール	説明
TDBGrid	データソースの情報を表計算ワークシートのようなグリッドに表示する。グリッドの列は，基礎となるテーブルまたは問い合わせのデータセットの列に対応している
TDBNavigator	データセットのデータレコード間の移動，レコードの更新，登録，削除，編集の取り消し，データ表示の更新用に設定可能なボタンセットを提供する
TDBText	項目のデータをラベルとして表示する
TDBEdit	項目のデータを編集ボックスに表示する
TDBMemo	メモ型項目または BLOB 項目のデータを複数行の編集ボックスに表示する
TDBRichEdit	メモ型項目のデータを，書式付きで複数行の編集ボックスに表示する
TDBImage	データ項目のビットマップ，アイコン，メタファイルをグラフィックボックスに表示する
TDBListBox	現在のデータレコードの項目を更新するために選択可能な項目名のリストを表示する
TDBComboBox	項目を更新するために選択可能な項目名のリストを表示する。また，標準のデータベース対応編集ボックスと同じようにテキストの直接入力も可能にする
TDBCheckBox	論理型項目の値を示すチェックボックスを表示する
TDBRadioGroup	項目に対して同時に複数は選択できないオプションセットを表示する
TDBLookupListBox	項目の値に基づいてほかのデータセットを参照し，項目名のリストを表示する
TDBLookupComboBox	項目の値に基づいてほかのデータセットを参照し，項目名のリストを表示する。また，標準のデータベース対応編集ボックスと同じようにテキストの直接入力も可能にする
TDBCtrlGrid	設定可能な繰り返しのデータベース対応コントロールセットをグリッド内に表示する
TDBChart	データソースの情報を棒グラフや折れ線グラフなどに表示する
設計時にコントロールの DataSource プロパティをアクティブなデータソースに設定すると，そのコントロールにはただちに実際のデータが表示されます。項目エディタを使うと，アプリケーションをコンパイルして実行しなくても，設計時にデータセットをスクロールしてアプリケーションがデータを正しく表示することを確認できます。項目エディタについての詳細は，「持続的項目の作成」を参照してください。

実行時には，データコントロールはデータを表示し，アプリケーションとそのコントロールとデータベースのすべてで許可されていれば，ユーザーはそのコントロールを通してデータを編集できます。


Displaying and editing data in a data-aware control
Displaying and editing data in a data-aware control1083003

Section topics 	参照

データコントロールにデータを表示する手順は次のとおりです。

1.	データセットとデータソースをデータモジュールまたはフォームに配置し，そのプロパティを必要に応じて設定します。

2.	コンポーネントパレットの［Data Access］ページにあるデータセットコンポーネントとデータソースコンポーネントをフォームに配置し関連付けをします。

3.	コントロールの DataSource プロパティをデータの取得元データソースコンポーネントの名前に設定します。データソースコンポーネントは，データの入ったデータセットとコントロールとの仲介の役目を果たします。

4.	コントロールの DataField プロパティを表示項目の名前に設定するか，DataField プロパティのドロップダウンリストの項目名を選択します。この手順は TDBGrid，TDBCtrlGrid，TDBNavigator には適用されません。それらのコントロールはデータセット内の利用可能なすべての項目にアクセスするからです。

5.	コントロールにデータを表示するには，データセットの Active プロパティを True に設定します。


Enabling mouse, keyboard, and timer events
Enabling mouse, keyboard, and timer events1083004

Section topics 	参照

データコントロールの Enabled プロパティは，そのデータコントロールがマウス，キーボード，タイマーのイベントに応答して，データソースに情報を渡すかどうかを決めます。Enabled プロパティのデフォルトの設定は True です。

マウス，キーボード，タイマーのイベントがデータコントロールにアクセスできないようにするには，データコントロールの Enabled プロパティを False に設定します。Enabled が False の場合，データソースはデータコントロールから情報を受け取りません。データコントロールはデータを表示し続けますが，このデータコントロールに表示されるテキストは淡色表示になります。


Enabling editing in controls on user entry
Enabling editing in controls on user entry1083005

Section topics 	参照

データセットのデータを編集できるようにするには，そのデータセットを dsEdit 状態にしなければなりません。コントロールが結び付けられているデータソースの AutoEdit プロパティは，キーボードまたはマウスのイベントに応じてコントロールのデータが変更されるときに，基になるデータセットが dsEdit モードになるかどうかを決めます。AutoEdit が True の場合（デフォルト），編集が始まるとすぐに dsEdit モードが設定されます。AutoEdit が False の場合，ユーザーが実行時に dsEdit 状態を設定できるようにするには，TDBNavigator コントロールにレコード編集のボタン（またはその他のメソッド）を用意しなければなりません。TDBNavigator についての詳細は「レコード間の移動と操作」を参照してください。


Editing data in a control
Editing data in a control1083006

Section topics 	参照

データコントロールの ReadOnly プロパティは，そのコントロールによって表示されたデータをユーザーが編集できるかどうかを決めます。ReadOnly が False の場合（デフォルト），ユーザーはデータを編集できます。ユーザーがコントロールのデータを編集できないようにするには，ReadOnly を True に設定します。

コントロールの基礎となるデータソースとデータセットのプロパティでも，ユーザーがコントロールのデータを編集して，その結果をデータセットに登録できるかどうかを決めます。

データソースの Enabled プロパティは，データソースに結び付けられたコントロールがそのデータセットの項目値を表示できるかどうかを決めます。したがって，ユーザーが項目値を編集して登録できるかどうかも決めることになります。Enabled が True の場合（デフォルト），コントロールは項目値を表示できます。

データセットの ReadOnly プロパティは，ユーザーによる編集の結果をそのデータセットに登録できるかどうかを決めます。ReadOnly が False の場合（デフォルト）は編集結果をデータセットに登録でき，True の場合はデータセットは読み出し専用になります。

メモ	読み出し専用の実行時プロパティ CanModify は，データセットを変更できるかどうかを決めます。CanModify が True の場合はデータベースへの書き込みアクセスが許可され，False の場合はデータセットは読み出し専用になります。挿入と更新を行う問い合わせコンポーネントは，基礎となるデータベース自体に対して必要なだけの書き込み特権がアプリケーションとユーザーにあれば，そのデータベースへの書き込みができることになっています。

表に示すのは，ユーザーがコントロールのデータを編集して，その結果をデータベースに登録できるかどうかを決める要因です。

データコントロール の ReadOnly  プロパティ	データソース の Enabled  プロパティ	データセット の ReadOnly  プロパティ	データセット の CanModify  プロパティ	データベース への書き込み アクセス	データベース への書き込み
False	True	False	True	読み書き	できる
False	True	False	False	読み出し専用	できない
False	False	--	--	--	できない
True	--	--	--	--	できない
TDBGrid を除くすべてのデータコントロールでは，項目を変更した場合，〔Tab〕でコントロールから離れるときにデータセット内の基になる項目コンポーネントに変更がコピーされます。〔Tab〕で項目から移動する前に〔Esc〕を押すと，変更が破棄され，項目の値は変更前の値に戻ります。

TDBGrid では，別のレコードに移動したときだけ変更がコピーされます。別のレコードに移動する前に項目のレコードで〔Esc〕を押すと，レコードに対するすべての変更を取り消せます。

レコードを登録するときに，データセットに関連付けられたすべてのデータベース対応コンポーネントの状態の変化が調べられます。変更のあるデータを含む項目を更新するときに問題が発生すると，例外が生成されて，レコードへの変更は行われません。


Disabling and enabling data display
Disabling and enabling data display1083007

Section topics 	参照

アプリケーションがデータセットの繰り返し処理または検索をするときは，現在のレコードが変更されるたびにデータベース対応コンポーネントに表示されている値が更新されないように設定を一時的に変えるとよいでしょう。値が更新されないようにすると，繰り返し処理や検索の速度が上がり，目障りな画面のちらつきが起こりません。

DisableControls は，データセットにリンクされたすべてのデータベース対応コントロールの表示を無効にするデータセットのメソッドです。繰り返し処理や検索が終わったら，すぐにアプリケーションはデータセットの EnableControls メソッドを呼び出して，コントロールの表示を再び有効にしなければなりません。

通常は，繰り返し処理の前にコントロールを使用不可にします。繰り返し処理自体は，処理中に例外が生成されてもコントロールを再び使用可能にできるように，try...finally 文の内部で発生させなければなりません。finally 節では，EnableControls を呼び出さなければなりません。次のコードは，このようにして DisableControls と EnableControls を使う方法を示しています。

CustTable.DisableControls;

try

  CustTable.First; { 最初のレコードに移動する。その結果，EOF は False になる }

  while not CustTable.EOF do { EOF が True になるまで繰り返す }

  begin

    { ここで各レコードを処理する }

    ...

    CustTable.Next; { 成功すると EOF は False になる。
最後のレコードで Next が失敗すると EOF は True になる }

  end;

finally

  CustTable.EnableControls;

end;


Refreshing data
Refreshing data1083008

Section topics 	参照

データセットの Refresh メソッドは，ローカルバッファの内容を消去して，開いているデータセット用にデータを取得し直します。アプリケーションで使っているデータにほかの複数のアプリケーションが同時にアクセスしてきたため，基礎となるデータが変更されていると考えられる場合に，この Refresh メソッドを使うとデータベース対応コントロールの表示を更新できます。

重要	更新により，予期しない結果になることがあります。たとえば，ほかのアプリケーションで削除されたレコードをユーザーが表示している場合，アプリケーションが Refresh を呼び出すと，ただちにそのレコードが消去されます。初めにデータを取得した後で Refresh を呼び出す前に，ほかのユーザーがレコードを変更した場合も，データの表示状態が変化することがあります。


Displaying data as labels
Displaying data as labels1083009

Section topics 	参照

TDBText は，コンポーネントパレットの［Standard］ページにある TLabel コンポーネントに似た読み出し専用のコントロールです。TDBText コントロールは，ユーザーがほかのコントロールに入力を行うためのフォームに，表示専用データを提供する場合に役立ちます。たとえば，顧客リストテーブルの項目に基づいて作成されたフォームを考えます。ユーザーがフォームに都道府県，市区町村，番地の情報を入力すると，動的参照によって自動的に別のテーブルから郵便番号項目を取得するとします。ここで，TDBText コンポーネントを郵便番号テーブルに結合すると，ユーザーが入力した住所に該当する郵便番号項目を表示できます。

TDBText は，データセットの現在のレコード内の指定された項目から，表示するテキストを取得します。TDBText はデータセットからテキストを取得するため，表示されるテキストは動的なテキストです。つまり，ユーザーがデータベーステーブル内を移動するにつれてテキストは変化します。したがって，TLabel とは異なり，設計時に TDBText の表示テキストを指定することはできません。

メモ	フォームに TDBText コンポーネントを配置する場合は，その AutoSize プロパティを True に設定しておき（デフォルト），表示するデータの幅に合わせてコントロールがそのサイズを変更できるようにします。AutoSize を False に設定した場合，コントロールが小さすぎると，データ表示の一部が切り捨てられます。


Displaying and editing fields in an edit box
Displaying and editing fields in an edit box1083010

Section topics 	参照

TDBEdit は，編集ボックスコンポーネントのデータベース対応バージョンです。TDBEdit は，リンク先のデータ項目の現在値を表示します。この値は，標準の編集ボックスの操作方法で編集できます。

たとえば CustomersSource が，CustomersTable という開いている TTable にリンクされたアクティブな TDataSource コンポーネントであるとします。ここで，TDBEdit コンポーネントをフォームに配置して，そのプロパティを以下のように設定します。

DataSource は CustomersSource

DataField は CustNo

データベース対応の編集ボックスコンポーネントは，設計時にも実行時にも，CustomersTable データセットの CustNo 列にある現在の行の値をただちに表示します。


Displaying and editing text in a memo control
Displaying and editing text in a memo control1083011

Section topics 	参照

TDBMemo は，標準の TMemo コンポーネントに似たデータベース対応コンポーネントですが，バイナリ大規模オブジェクト（BLOB）データを表示できます。TDBMemo では複数行テキストが表示され，ユーザーによる複数行テキストの入力も可能になります。TDBMemo コントロールを使うと，dBASE テーブルや Paradox テーブルのメモ型項目や，BLOB 項目に含まれているテキストデータを表示できます。

デフォルトでは，TDBMemo はユーザーによるメモテキストの編集を許可します。編集を防止するには，メモコントロールの ReadOnly プロパティを True に設定します。タブを表示してユーザーがメモでタブを入力できるようにするには，WantTabs プロパティを True に設定します。ユーザーがデータベースのメモに入力できる文字の数を制限するには，MaxLength プロパティを使います。MaxLength のデフォルト値は 0 で，これは文字数に制限がないことを意味します。

データベースのメモの外観とテキストの入力方法には，いくつかのプロパティが影響します。メモにスクロールバーを追加するには，ScrollBars プロパティを使います。ワードラップを抑止するには，WordWrap プロパティを False に設定します。コントロール内でのテキストの揃え方は，Alignment プロパティの値を taLeftJustify（デフォルト），taCenter，taRightJustify のいずれかに設定して決めます。テキストのフォントを変更するには，Font プロパティを使います。

実行時にユーザーは，データベースのメモコントロールとの間でテキストの切り取り，コピー，貼り付けができます。プログラムで同じ作業をするには，CutToClipboard，CopyToClipboard，PasteFromClipboard の各メソッドを使います。

TDBMemo は大量のデータを表示できるため，実行時の表示に時間がかかることがあります。データレコードのスクロールにかかる時間を減らすため，TDBMemo には，アクセスされたデータを自動的に表示するかどうかを制御する AutoDisplay プロパティがあります。AutoDisplay を False に設定すると，TDBMemo は実際のデータではなく項目名を表示します。実際のデータを表示するには，コントロール内をダブルクリックします。


Displaying and editing text in a rich edit memo control
Displaying and editing text in a rich edit memo control1083012

Section topics 	参照

TDBRichEdit は標準の TRichEdit コンポーネントに似たデータベース対応コンポーネントで，バイナリ大規模オブジェクト（BLOB）データを表示できます。TDBRichEdit は，書式付きの複数行テキストを表示し，ユーザーによる書式付きの複数行テキストの入力も許可します。TDBRichEdit コントロールを使うと，dBASE テーブルや Paradox テーブルのメモ型項目や，BLOB 項目に含まれているテキストデータを表示できます。

メモ	TDBRichEdit は書式付きテキストを入力して操作するためのプロパティとメソッドを提供しますが，このような書式設定オプションをユーザーが利用できるようにするためのユーザーインターフェースコンポーネントを提供することはありません。アプリケーションが書式付きテキストの機能のためのユーザーインターフェースを実装しなければなりません。

デフォルトでは，TDBRichEdit はユーザーによるメモテキストの編集を許可します。編集を防止するには，書式付きテキスト編集コントロールの ReadOnly プロパティを True に設定します。タブを表示してユーザーがメモでタブを入力できるようにするには，WantTabs プロパティを True に設定します。ユーザーがデータベースのメモに入力できる文字の数を制限するには，MaxLength プロパティを使います。MaxLength のデフォルト値は 0 で，これは文字数に制限がないことを意味します。

TDBRichEdit は大量のデータを表示できるため，実行時の表示に時間がかかることがあります。データレコードのスクロールにかかる時間を減らすため，TDBRichEdit には，アクセスされたデータを自動的に表示するかどうかを制御する AutoDisplay プロパティがあります。AutoDisplay を False に設定すると，TDBRichEdit は実際のデータではなく項目名を表示します。実際のデータを表示するには，コントロール内をダブルクリックします。


Displaying and editing graphics fields in an image control
Displaying and editing graphics fields in an image control1083013

Section topics 	参照

TDBImage は，BLOB データ項目に含まれているビットマップグラフィックを表示するデータベース対応コンポーネントです。データセットから BLOB グラフィックイメージを取得して，内部的には Windows の .DIB 形式で格納します。

デフォルトでは，TDBImage は，ユーザーが CutToClipboard，CopyToClipboard，PasteFromClipboard の各メソッドを使ってクリップボードとの間で切り取りと貼り付けを行うことで，グラフィックイメージを編集するのを許可します。かわりに，イベントハンドラに結び付けられた独自の編集メソッドをこのコントロールに与えることもできます。

デフォルトでは，イメージコントロールはそれに収まる量のグラフィックを表示します。イメージコントロールのサイズを変更したときにその内部に収まるようグラフィックを再調整するには，Stretch プロパティを True に設定します。

TDBImage は大量のデータを表示できるため，実行時の表示に時間がかかることがあります。データレコードのスクロールにかかる時間を減らすため，TDBImage には，アクセスされたデータを自動的に表示するかどうかを制御する AutoDisplay プロパティがあります。AutoDisplay を False に設定すると，TDBImage は実際のデータではなく項目名を表示します。実際のデータを表示するには，コントロール内をダブルクリックします。


Displaying and editing data in list and combo boxes
Displaying and editing data in list and combo boxes1083014

Section topics 	参照

標準のリストボックスコントロールとコンボボックスコントロールのデータベース対応バージョンとして，4 つのデータコントロールがあります。この便利なコントロールは，実行時に一連のデフォルトのデータ値を選択肢としてユーザーに提供します。

メモ	データベース対応のリストボックスとコンボボックスがリンクの相手にできるのは，テーブルコンポーネントのデータソースだけです。問い合わせコンポーネントには使えません。

表に各コントロールの説明を示します。

データコントロール	説明
TDBListBox	現在のレコードの項目を更新するために選択可能な項目名のリストを表示する。表示される項目名のリストは，コントロールのプロパティで指定する
TDBComboBox	編集ボックスとリストボックスを兼ね備えている。ユーザーはドロップダウンリストの値を選択するか値を入力して，現在のレコードの項目を更新できる。表示される項目名のリストは，コントロールのプロパティで指定する
TDBLookupListBox	現在のレコードの列を更新するために選択可能な項目名のリストを表示する。表示される項目名のリストは，ほかのデータセットを参照した値が入る
TDBLookupComboBox	編集ボックスとリストボックスを兼ね備えている。ユーザーはドロップダウンリストの値を選択するか値を入力して，現在のレコードの項目を更新できる。表示される項目名のリストは，ほかのデータセットを参照した値が入る


Displaying and editing data in a list box
Displaying and editing data in a list box1083015

Section topics 	参照

TDBListBox は，スクロール可能な項目値のリストを表示します。ユーザーはこのリストの項目値を選択して，データ項目に入力できます。データベース対応リストボックスは，現在のレコードの項目に対応する値を強調表示します。現在の行の項目値がリストにない場合，リストボックスで強調表示される値はありません。ユーザーがリストの項目値を選択すると，基になるデータセットで対応する項目値が変更されます。

設計時に文字列リストエディタを使って，表示する項目名のリストを Items プロパティに作成します。ItemHeight プロパティは，リストボックスに一度に表示される項目名の数を決めます。IntegralHeight プロパティは，リストボックスの表示方法を制御します。IntegralHeight が False の場合（デフォルト），リストボックスの下端が ItemHeight プロパティによって決まるので，一番下の項目名が完全には表示されないことがあります。IntegralHeight が True の場合，リストボックスの一番下の項目名まで完全に表示されます。


Displaying and editing data in a combo box
Displaying and editing data in a combo box1083016

Section topics 	参照

TDBComboBox コントロールは，データベース対応編集コントロールとドロップダウンリストの両方の機能を兼ね備えています。実行時に TDBComboBox コントロールが表示するドロップダウンリストで，ユーザーは定義済みの一連の値から選択できます。ユーザーはまったく別の値を入力することもできます。

コンポーネントの Items プロパティは，ドロップダウンリストに含まれる項目名を指定します。設計時には，文字列リストエディタを使用して項目名リストの項目を決めます。実行時には，Item プロパティのメソッドを使用してその文字列を操作します。

DataField プロパティを使ってコントロールを項目にリンクすると，現在の行にある項目の値が項目名リストに含まれているかどうかに関係なく，コントロールはその値を表示します。Style プロパティは，ユーザーとコントロールとの対話の方法を決めます。デフォルトでは Style は csDropDown で，ユーザーがキーボードを使った値の入力や，ドロップダウンリストの項目名の選択ができることを表します。実行時に項目名リストがどのように表示されるかを決めるプロパティは，以下のとおりです。

Style は，コンポーネントの表示スタイルを決める

csDropDown の場合（デフォルト），ユーザーがテキストを入力できる編集ボックスのあるドロップダウンリストを表示する。すべての項目名は同じ高さの文字列である

csSimple の場合，ドロップダウンリストを表示しない

csDropDownList の場合，ドロップダウンリストと編集ボックスを表示するが，ユーザーは実行時にドロップダウンリストにない値の入力や変更ができない

csOwnerDrawFixed と csOwnerDrawVariable の場合，項目名リストには文字列以外の値（ビットマップなど）を表示できる。

DropDownCount は，リストに表示される項目名の最大数を決める。Items の項目名の数が DropDownCount の値より大きい場合，ユーザーはリストをスクロールできる。Items の項目名の数が DropDownCount の値より小さい場合，リストはすべての項目名が収まるだけのサイズになる

ItemHeight は，スタイルが csOwnerDrawFixed の場合に各項目名の高さを決める

Sorted は，True ならば Items リストをソートして表示する


Displaying and editing data in lookup list and combo boxes
Displaying and editing data in lookup list and combo boxes1083017

Section topics 	参照

TDBLookupListBox と TDBLookupComboBox は，表示する項目名のリストを以下のいずれかから取得するデータベース対応コントロールです。

データセットに定義された参照項目

二次データソース，データ項目，キー

いずれの場合も，有効な項目値を設定するための選択肢からなる一定のリストがユーザーに提供されます。ユーザーがリストの項目を選択すると，対応するデータセットの項目値が変更されます。

たとえば，OrdersTable に結合された項目を持つ注文フォームを考えます。OrdersTable には顧客 ID に対応した CustNo 項目はありますが，ほかの顧客情報はありません。これに対して，CustomersTable には顧客 ID に対応した CustNo 項目だけでなく，顧客の会社名や住所などの追加情報もあります。事務員が請求書を作成するときに，注文フォームで顧客 ID ではなく会社名によって顧客を選択できれば便利です。CustomersTable のすべての会社名を表示する TDBLookupListBox を使うと，ユーザーはリストの会社名を選択して，注文フォームの CustNo を適切な値に設定できます。


Specifying a list based on a lookup field
Specifying a list based on a lookup field1083018

Section topics 	参照

参照項目を使ってリストボックスの項目名を指定するには，そのコントロールにリンクされているデータセットで参照項目を定義しておかなければなりません。データセットでの参照項目の定義についての詳細は，「参照項目を定義する」を参照してください。

リストボックスの項目名に対する参照項目を指定する手順は次のとおりです。

1.	リストボックスの DataSource プロパティを，参照項目を持つデータセットを示すデータソースに設定します。

2.	DataField プロパティに対し，使いたい参照項目をドロップダウンリストから選択します。

参照リストボックスコントロールに関連付けられたテーブルをアクティブにすると，そのコントロールは指定されたデータ項目が参照項目であると認識し，参照項目の適切な値を表示します。


Specifying a list based on a secondary data source
Specifying a list based on a secondary data source1083019

Section topics 	参照

データセットに参照項目を定義していない場合，二次データソース，二次データソースで検索する項目値，リストの項目名として返される項目値を使って，同じような関係を確立できます。

リストボックスの項目名に対する二次データソースを指定する手順は次のとおりです。

1.	リストボックスの DataSource プロパティを元となるデータソースに設定します。

2.	DataField プロパティに対し，参照元となる項目をドロップダウンリストから選択します。ここには参照項目は選択できません。

3.	リストボックスの ListSource プロパティを，参照先の項目を持つデータセットのデータソースに設定します。

4.	KeyField プロパティに対し，キーとして使う項目をドロップダウンリストから選択します。ドロップダウンリストには，手順の 3 で指定したデータソースに関連付けられているデータセットの項目が表示されます。インデックスの付いた項目を選択する必要はありませんが，インデックス付きの項目を選択すると，参照の処理効率が上がります。

5.	ListField プロパティに対し，参照の結果として返される値を含む項目をドロップダウンリストから選択します。ドロップダウンリストには，手順 3 で指定したデータソースに関連付けられているデータセットの項目が表示されます。

参照リストボックスのコントロールに関連付けられたテーブルをアクティブにすると，そのコントロールはリストの項目名が二次ソースから取得されていると認識し，その二次ソースの適切な値を表示します。


Setting lookup list and combo box properties
Setting lookup list and combo box properties1083020

Section topics 	参照

表に参照リストボックスとコンボボックスに固有の重要なプロパティを示します。

プロパティ	用途
DataField	参照データセットで参照するキー値を提供する，マスターデータセットの項目を指定する。ユーザーがリストボックスの項目名を選択すると，この項目が変更される。DataField を参照項目に設定した場合，KeyField，ListField，ListSource の各プロパティは使わない
DataSource	コントロールの元データソースを指定する。コントロール内のセクションが変更された場合は，データセットは dsEdit モードになる
KeyField	DataField の項目に対応する，参照先データセットの項目を指定する。コントロールは，参照データセットの KeyField の項目で DataField の項目の値を検索する。参照の効率を上げるには，参照先データセットが KeyField 項目のインデックスを持つことが必要である
ListField	コントロールで表示する，参照データセットの項目を指定する
ListSource	二次（参照先）データセットのデータソースを指定する。リストボックスに表示される項目名のソート順は，参照先データセットの IndexName プロパティで指定するインデックスによって決まる。このインデックスは，KeyField プロパティで使われるインデックスと同じにする必要はない
RowCount	TDBLookupListBox のみリストボックスに表示するテキストの行数を指定する。リストボックスの高さは，この行数にちょうど合うように調節される
DropDownRows	TDBLookupComboBox のみ。ドロップダウンリストに表示するテキストの行数を指定する


Searching incrementally for list item values
Searching incrementally for list item values1083021

Section topics 	参照

実行時にユーザーは，インクリメンタルサーチによってリストボックスの項目名を検索できます。このコントロールにフォーカスがあるときに，たとえば「ROB」と入力すると，「ROB」という文字列で始まる最初の項目名がリストボックスで選択されます。続けて「E」と入力すると，「Robert Johnson」のように，「ROBE」で始まる最初の項目名が選択されます。検索では，大文字と小文字は区別されません。キー入力とキー入力の間が 2 秒以上空いた場合，または〔BS〕や〔Esc〕を押すと，現在の検索文字列が取り消されます（ただし選択された項目はそのまま残ります）。


Handling Boolean field values with check boxes
Handling Boolean field values with check boxes1083022

Section topics 	参照

TDBCheckBox はデータベース対応のチェックボックスコントロールです。TDBCheckBox を使うと，データセット内の論理型項目の値を設定できます。たとえば，顧客あての請求書フォームにチェックボックスコントロールを配置して，チェックマークを付けると顧客を非課税扱いにし，チェックマークをはずすと顧客を非課税扱いにしないように定義できます。

データベース対応チェックボックスコントロールはそのチェックボックスのチェック状態と非チェック状態の管理を，現在の項目値と ValueChecked プロパティおよび ValuedUnchecked プロパティの内容を比較して行います。項目値が ValueChecked プロパティと一致した場合，コントロールにチェックマークが付きます。そうでなく，項目が ValueUnchecked プロパティと一致した場合は，コントロールのチェックマークがはずれます。

メモ	ValueChecked と ValuedUnchecked の値は同じにはできません。

コントロールにチェックマークが付いている場合，ユーザーが別のレコードに移動したときに，ValueChecked プロパティに設定した値がデータベースに登録されます。デフォルトではこの値は「True」に設定されていますが，必要であれば任意の文字型項目値に変更できます。ValueChecked の値としては，セミコロンで区切った要素のリストも指定できます。いずれかの要素が現在のレコードにある項目の内容に一致する場合，チェックボックスにチェックマークが付きます。たとえば，次のように ValueChecked の文字列を指定します。

DBCheckBox1.ValueChecked := 'True;Yes;On';

現在のレコードの項目の値が True，Yes，または On の場合，チェックボックスにチェックマークが付きます。項目と ValueChecked の文字列との比較では，大文字と小文字は区別されません。ユーザーが複数の ValueChecked 文字列のあるボックスにチェックマークを付けた場合は，最初の文字列がデータベースに登録される値になります。

コントロールにチェックマークが付いていない場合，ユーザーが別のレコードに移動したときに，ValueUnchecked プロパティに設定した値がデータベースに登録されます。デフォルトではこの値は「False」に設定されていますが，必要であれば任意の文字型項目値に変更できます。ValueUnchecked の値としては，セミコロンで区切った要素のリストも指定できます。いずれかの要素が現在のレコードにある項目の内容に一致する場合，チェックボックスのチェックマークがはずされます。

データベース対応チェックボックスは，現在のレコードにある項目の内容が ValueChecked プロパティまたは ValueUnchecked プロパティに指定されたどの値とも一致しない場合は，使用不可になります。

チェックボックスが関連付けられている項目が論理型項目の場合は，項目の内容が True であれば常にチェックボックスにチェックマークが付き，項目の内容が False であればチェックマークがはずされます。この場合，ValueChecked プロパティと ValueUnchecked プロパティに指定された文字列は論理型項目に影響を与えません。


Restricting field values with radio controls
Restricting field values with radio controls1083023

Section topics 	参照

TDBRadioGroup はラジオグループコントロールのデータベース対応バージョンです。TDBRadioGroup を使うと，とりうる値が限られているデータ項目に対して，ラジオボタンコントロールで値を設定できます。ラジオグループの各ボタンは，項目がとりうる値のそれぞれに対応しています。ユーザーは，目的のラジオボタンを選択すれば，データ項目の値を設定できます。

Items プロパティは，グループ内のラジオボタンの数を決める文字列リストです。表示される各ラジオボタンは，Items の文字列のそれぞれに対応しています。各文字列は，ラジオボタンのラベルとして，対応するラジオボタンの右側に表示されます。

ラジオグループに関連付けられている項目の現在値が Items プロパティの文字列のいずれかと一致する場合，そのラジオボタンが選択されます。たとえば，Red，Yellow，Blue という 3 つの文字列をこの順番で Items に指定した場合，現在のレコードの項目の値が Blue であれば，グループの 3 番目のボタンが選択されます。

メモ	項目が Items のどの文字列とも一致しない場合でも，項目が Values プロパティの文字列と一致すれば，ラジオボタンは選択されます。現在のレコードの項目が Items と Values のどの文字列にも一致しない場合は，ラジオボタンは選択されません。

Values プロパティには，ユーザーがラジオボタンを選択してレコードを登録したときにデータセットに返す文字列のリストを，オプションで指定できます。文字列は順番にボタンに関連付けられます。最初の文字列は最初のボタンに，2 番目の文字列は 2 番目のボタンに，という具合に関連付けられます。たとえば，Items に Red，Yellow，Blue をこの順番で指定し，Values に Magenta，Yellow，Cyan をこの順番で指定している場合，ユーザーが Red というラベルのボタンを選択すると，Magenta がデータベースに登録されます。

Values に文字列を指定していない場合は，選択されたラジオボタンの Items の文字列がレコードの登録時にデータベースに返されます。


Navigating and manipulating records
Navigating and manipulating records1083024

Section topics 	参照

TDBNavigator を使うと，ユーザーはデータセットのレコード間の移動とレコードの操作を簡単に制御できます。ナビゲータは一連のボタンで構成されます。ナビゲータのボタンを使うと，ユーザーは一度に 1 件ずつレコードを前後にスクロールできます。また，最初のレコードへの移動，最後のレコードへの移動，新規レコードの挿入，既存のレコードの更新，データ変更の登録，データ変更の取り消し，レコードの削除，レコード表示の更新などもできます。

図に，設計時にフォームへ配置したときにデフォルトで表示されるナビゲータを示します。ナビゲータの各ボタンは，データセットのレコード間の移動やレコードの編集，削除，挿入，登録をユーザーが行えるようにするものです。ナビゲータの VisibleButtons プロパティを使うと，このようなボタンの一部を動的に表示したり非表示にしたりできます。

表に TDBLookupComboBox に固有の重要なプロパティを示します。

ボタン	用途
最初のレコード	データセットの First メソッドを呼び出して，現在のレコードを最初のレコードに設定する
前のレコード	データセットの Prior メソッドを呼び出して，現在のレコードを前のレコードに設定する
次のレコード	データセットの Next メソッドを呼び出して，現在のレコードを次のレコードに設定する
最後のレコード	データセットの Last メソッドを呼び出して，現在のレコードを最後のレコードに設定する
レコードの挿入	データセットの Insert メソッドを呼び出して，現在のレコードの直前に新規レコードを挿入し，データセットを挿入状態にする
現在のレコードの削除	現在のレコードを削除する。ConfirmDelete プロパティが True の場合，削除する前に確認のメッセージが表示される
現在のレコードの編集	現在のレコードを変更できるように，データセットを編集状態にする
レコード編集の登録	現在のレコードの変更内容をデータベースに書き込む
レコード編集の取り消し	現在のレコードの編集内容を取り消し，データセットを参照状態に戻す
レコードの更新	データコントロールの表示バッファをクリアし，物理テーブルや問い合わせによってそのバッファを更新する。基礎となるデータが別のアプリケーションで変更された可能性がある場合に役立つ


Choosing navigator buttons to display
Choosing navigator buttons to display1083025

Section topics 	参照

設計時に初めてフォームに TDBNavigator を配置したときは，そのすべてのボタンが表示されます。VisibleButtons プロパティを使うと，フォームで使わないボタンを非表示にできます。たとえば，編集を行わず参照だけを行うフォームでは，レコードの編集，挿入，削除とレコード編集の登録，取り消しのための各ボタンを消去できます。

Hiding and showing navigator buttons at design time1083026

VisibleButtons プロパティは，オブジェクトインスペクタで +（正符号）付きで表示されます。これは，VisibleButtons プロパティを展開して，ナビゲータの各ボタンの論理値を表示できることを表します。論理値を表示して設定するには，VisibleButtons プロパティをダブルクリックします。オブジェクトインスペクタの VisibleButtons プロパティの下に，ボタンのリストが表示されます。ここで，各ボタンの表示と非表示を切り替えられます。+ が -（負符号）に変化したときは，VisibleButtons プロパティをダブルクリックすればプロパティのリストを折りたためることを表します。

ボタンが表示されるかどうかは，ボタンの値の論理状態で示されます。値が True の場合，ボタンは TDBNavigator に表示されます。False の場合，設計時にも実行時にも，ボタンはナビゲータから削除されます。

メモ	あるボタンの値を False に設定すると，そのボタンはフォームの TDBNavigator から削除され，残りのボタンがこのコントロールの幅全体に広がります。コントロールのハンドルをドラッグすれば，ボタンのサイズを変更できます。

ボタンおよびボタンが呼び出すメソッドについての詳細は，オンラインヘルプの「VCL リファレンス」を参照してください。

Hiding and showing navigator buttons at run time1083027

ユーザーの操作やアプリケーションの状態に応じて，実行時にナビゲータのボタンを消去することも表示することもできます。たとえば，単一のナビゲータを使って 2 種類のデータセットでレコード間の移動をする場合を考えます。一方のデータセットはユーザーのレコード編集が可能で，もう一方のデータセットは読み出し専用とした場合，レコードの挿入，削除，編集，更新とレコード編集の登録，取り消しに使うナビゲータの各ボタンは，読み出し専用のデータセットでは消去し，レコード編集が可能なデータセットでは表示するようにします。

たとえば，OrdersTable ではレコードの挿入，削除，編集，更新とレコード編集の登録，取り消しに使うナビゲータの各ボタンを消去して編集ができないようにし，CustomersTable では編集ができるようにすることが考えられます。ナビゲータにどのボタンを表示するかは，VisibleButtons プロパティで決めます。次に OnEnter イベントハンドラの記述例を示します。

procedure TForm1.CustomerCompanyEnter(Sender :TObject);

begin

  if Sender = CustomerCompany then

  begin

    DBNavigatorAll.DataSource := CustomerCompany.DataSource;

    DBNavigatorAll.VisibleButtons := [nbFirst,nbPrior,nbNext,nbLast];

  end

  else

  begin

    DBNavigatorAll.DataSource := OrderNum.DataSource;

    DBNavigatorAll.VisibleButtons := DBNavigatorAll.VisibleButtons + [nbInsert,

      nbDelete,nbEdit,nbPost,nbCancel,nbRefresh];

  end;

end;


Displaying fly-over help
Displaying fly-over help1083028

Section topics 	参照

実行時にナビゲータの各ボタンについてのヘルプヒントを表示するには，ナビゲータの ShowHints プロパティを True に設定します。ShowHints が True の場合，マウスカーソルがナビゲータのボタンの上にくると，ヘルプヒントが表示されます。ShowHints はデフォルトでは False です。

Hints プロパティは，各ボタンのヘルプヒントのテキストを制御します。デフォルトでは，Hints は空の文字列リストです。Hints が空の場合，各ボタンでデフォルトのヘルプテキストが表示されます。ナビゲータのボタンのヘルプヒントをカスタマイズするには，文字列リストエディタを使って，Hints プロパティで各ボタンに対する別のヒントテキストを入力します。入力した文字列は，ナビゲータコントロールが提供するデフォルトのヒントに優先します。


Using a single navigator for multiple datasets
Using a single navigator for multiple datasets1083029

Section topics 	参照

ほかのデータベース対応コントロールの場合と同じように，ナビゲータの DataSource プロパティは，そのコントロールをデータセットにリンクするデータソースを指定します。実行時にナビゲータの DataSource プロパティを変更すると，単一のナビゲータを使って，複数のデータセットでレコード間の移動とレコードの操作ができます。

フォームに 2 つの編集コントロールがあり，CustomersSource と OrdersSource の各データソースによってそれぞれ CustomersTable と OrdersTable のデータセットにリンクされているとします。CustomersSource に接続されている編集コントロールにユーザーが移動すると，ナビゲータも CustomersSource を使わなければなりません。OrdersSource に接続されている編集コントロールにユーザーが移動すると，ナビゲータも OrdersSource に切り替えなければなりません。次の例のようにすれば，編集コントロールの一方に対して OnEnter イベントハンドラを記述して，もう一方の編集コントロールとそのイベントハンドラを共有できます。

procedure TForm1.CustomerCompanyEnter(Sender :TObject);

begin

  if Sender = CustomerCompany then

    DBNavigatorAll.DataSource := CustomerCompany.DataSource

  else

    DBNavigatorAll.DataSource := OrderNum.DataSource;

end;


See also1083030

Data Access components

Data Controls components


Working with grids
Working with grids1084001

Section topics 	参照

この章では，データベース対応の TDBGrid コントロールを使って表形式のグリッドでデータセットレコードを表示したり編集する方法について説明します。グリッドは，Paradox や dBASE などのほとんどのデスクトップデータベースアプリケーションで利用可能なデータの表形式ビューつまりスプレッドシートに似たものです。アプリケーションはデータグリッドを使ってデータセットのレコードの編集，挿入，削除，表示ができます。グリッドでのデータと列の外観および利用可能性は，設計時と実行時の両方に表示用として静的な列を作成することで制御できます。

メモ	グリッドコントロールはほかのデータベース対応コントロールの共通機能を継承します。この共通機能については，「データコントロールの使い方」で説明しています。

さらにこの章では，グリッドに似た構造の中に，ほかのデータベース対応コンポーネントを繰り返し表示することができ，データベース対応グリッドコントロール TDBCtrlGrid（Delphi Client/Server で利用できます）についても紹介します。


Viewing and editing data with TDBGrid
Viewing and editing data with TDBGrid1084002

Section topics 	参照

TDBGrid コントロールは，データセットのレコードを表形式のグリッドで表示したり編集するのに使います。

TDBGrid コントロール

グリッドコントロールに表示されるレコードの外観に影響する 2 つの要因は以下のとおりです。

列エディタ（［カラム設定］ダイアログボックス）を使ってグリッド用に定義された静的な列オブジェクトがあるかどうか。静的な列オブジェクトを使うとグリッドやデータの外観の設定がかなり柔軟になる

グリッドに表示されるデータセットの静的な項目コンポーネントを作成するかどうか。項目エディタを使った静的な項目コンポーネントの作成についての詳細は，「項目の操作」を参照

グリッドコントロールは，それ自体が TDBGridColumns オブジェクトでのラッパーである Columns プロパティを持ちます。TDBGridColumns はグリッドコントロール内の列のすべてを表す TColumn オブジェクトのコレクションです。列エディタを使って設計時に列属性を設定することも，グリッドの Columns プロパティを使って実行時に TDBGridColumns のプロパティ，イベント，メソッドにアクセスすることもできます。

グリッドの Columns プロパティの State プロパティは，そのグリッドに対する静的な列オブジェクトが存在するかどうかを示します。Columns.State は実行時のみのプロパティで，グリッドに対して自動的に設定されます。Columns.State プロパティのデフォルトは csDefault で，そのグリッドについて列オブジェクトが存在しないことを意味します。その場合，グリッドへのデータの表示は，グリッドに表示されるデータセットの持続的項目コンポーネントによって決まるか，あるいは持続的項目コンポーネントがないデータセットについてはデータ表示のデフォルト条件で決まります。


Using a grid control in its default state
Using a grid control in its default state1084003

Section topics 	参照

グリッドの Columns.State プロパティが csDefault の場合，レコードの外観は主にグリッドのデータセットにある項目のプロパティで決まります。グリッド列はデータセットの表示可能な項目に基づいて動的に生成され，グリッド内の列の順序はデータセット内の項目の順序と一致します。グリッド内の列はそれぞれ 1 つの項目コンポーネントと関連付けられます。項目コンポーネントのプロパティが変わるとすぐグリッドに反映されます。

動的に生成された列を持ったグリッドコントロールを使うと，実行時に選択した任意のテーブルの内容を表示したり編集するのに便利です。グリッド構造が設定されていないため，動的に変化していろいろなデータセットを表示できます。動的に生成された列を持った単一グリッドは即座に Paradox テーブルを表示でき，グリッドの DataSource プロパティが変わったりデータソースそのものの DataSet プロパティが変わった場合には表示を切り替えて SQL の問い合わせ結果を表示できます。

設計時または実行時に動的な列の外観を変更できますが，実際に変更しているのは列に表示されている項目コンポーネントの対応するプロパティです。動的な列プロパティが存在するのは，列が単一のデータセット内の特定の項目と関連付けられている間だけです。たとえば，ある列の Width プロパティを変えるとその列に関連付けられている項目の DisplayWidth プロパティも変わります。Font のように項目プロパティに基づいていない列プロパティに対する変更はその列が残っている限り存続します。

動的な列のプロパティは，関連付けられている項目コンポーネントがある間は保持されます。グリッドのデータセットが動的な項目コンポーネントで構成されている場合，その項目はデータセットが閉じるたびに廃棄されます。項目コンポーネントが廃棄されると，それに関連付けられている動的な列もすべて廃棄されます。グリッドのデータセットが静的な項目コンポーネントで構成されている場合は，その項目コンポーネントはたとえデータセットが閉じても存続します。そのためその項目に関連付けられている列はデータセットが閉じてもそのプロパティを保持できます。

メモ	実行時にグリッドの Columns.State プロパティを csDefault に変えると，（静的な列も含めて）グリッドのすべての列オブジェクトは削除され，グリッドのデータセットの表示される項目に基づいて動的な列が再構築されます。


Creating a customized grid
Creating a customized grid1084004

Section topics 	参照

カスタマイズされたグリッドコントロールは，列の外観や列データの表示方法を記述する静的な列オブジェクトを定義するためのコントロールです。グリッドをカスタマイズすると，複数のグリッドを構成して同一のデータセットの表示（たとえば列順序，項目選択，列の色やフォント）をいろいろと変更できます。さらに，グリッドの使う項目やデータセットの項目順を変えずに実行時にグリッドの外観をユーザーが変更できるようになります。

カスタマイズされたグリッドは，設計時に構造のわかっているデータセットと一緒に使うのがもっとも望ましい方法です。カスタマイズされたグリッドは，設計時に設定した項目名がデータセットにあることを前提としているので，実行時に選択された任意のテーブルの参照に使うのはあまり適切ではありません。

Understanding persistent columns1084005

グリッドに作成した静的な列オブジェクトは，グリッドのデータセットの基になる項目とはあまり密接に関連付けられていません。静的な列プロパティのデフォルト値は，ある値がその列プロパティに代入されるまでデフォルトのソース（グリッドや関連付けられている項目）の中から動的に取得されます。列プロパティに値を代入するまではデフォルトのソースが変わるたびにその値も変化します。

たとえば，列タイトルキャプションのデフォルトソースは関連付けられている項目の DisplayLabel プロパティです。DisplayLabel プロパティを変更すると，ただちに列タイトルにその変更が反映されます。

いったん列プロパティに値を代入すると，デフォルトのソースが変わっても値は変わらなくなります。たとえば，列タイトルのキャプションに文字列を代入すると，そのタイトルキャプションは関連付けられている項目の DisplayLabel プロパティから独立します。以降はその項目の DisplayLabel プロパティを変えても列タイトルは変わりません。

静的な列は，関連付けられている項目コンポーネントから独立して存在しています。実際，静的な列は項目オブジェクトとまったく関連付けられていなくてもかまいません。静的な列の FieldName プロパティが空白の場合，あるいは項目名がグリッドの現在のデータセットにある項目名と一致しない場合，その列の Field プロパティは nil になり，空白のセルからなる列が描かれます。空白の列は，普通空白のセルになるところにレコードデータの特徴を描写するビットマップや棒グラフなどを表示するのに使えます。そのためには，そのセルのデフォルトの描画方法を変更しなければなりません。

2 つ以上の静的な列をデータセットの同一項目に関連付けることができます。たとえば，ワイドグリッドの左右の端に部品番号の項目を表示して，グリッドをスクロールしないでも部品番号を簡単に見つけられるようにできます。

メモ	静的な列をデータセットの項目と関連付ける必要がないため，また，複数の列で同一の項目を参照できるため，カスタマイズされたグリッドの FieldCount プロパティはグリッドの列数と等しいかそれ以下になります。また，カスタマイズされたグリッドの現在選択されている列がある項目と関連付けられていない場合，グリッドの SelectedField プロパティは nil になり，SelectedIndex プロパティは -1 になります。

グリッドのセルを別のデータセットや静的選択リストからの参照値のコンボボックスドロップダウンリストとして表示したり，現在のセルと関連した特殊なデータビューアやダイアログボックスをクリックで起動する省略記号のボタン（［...］）として表示するように静的な列を構成することができます。

Determining the source of a column property at run time1084006

実行時に列の AssignedValues プロパティをテストして，列プロパティが関連付けられている項目コンポーネントの値を取得しているのか，あるいは独自の値が代入されたのかを判別できます。

列の RestoreDefaults メソッドを呼び出せば，個々の列のプロパティをすべてデフォルトに戻すことができます。また，列リストの RestoreDefaluts を呼び出せば，グリッド内のすべての列のプロパティをデフォルトに戻すことができます。

DBGrid1.Columns.RestoreDefaults;

静的な列を追加するには，次のように列リストの Add メソッドを呼び出します。

DBGrid1.Columns.Add;

列オブジェクトを次のように解放するだけで静的な列を削除できます。

DBGrid1.Columns[5].Free;

最後の手順として，実行時に Columns.State プロパティに csCustomized を代入し，グリッドをカスタマイズモードにします。グリッドの既存の列は廃棄され，グリッドのデータセットの各項目に静的な列が新しく構築されます。


Creating persistent columns
Creating persistent columns1084007

Section topics 	参照

設計時にグリッドの外観をカスタマイズするには，列エディタ（［カラム設定］ダイアログボックス）を呼び出してグリッドの静的な列オブジェクトを作成します。実行時に静的な列オブジェクトを持つグリッドの Columns.State プロパティは自動的に csCustomized に設定されます。

グリッドコントロールの静的な列を作成する手順は次のとおりです。

1.	フォームのグリッドコンポーネントを選択します。

2.	オブジェクトインスペクタでグリッドの Columns プロパティの値列をダブルクリックして列エディタを呼び出せます。

リストボックスは，選択したグリッド用に定義されている静的な列を表示します。初めて列エディタを呼び出したときには，グリッドはデフォルト状態で動的な列しか含まないため，このリストは空です。

一度にデータセットのすべての項目に対して静的な列を作成することも，個々に静的な列を作成することもできます。

すべての項目に対して静的な列を作成する手順は次のとおりです。

1.	グリッドを右クリックしてコンテキストメニューを呼び出し，［すべての項目の追加(I)］を選択します。グリッドがデータソースとまだ関連付けられていない場合，［すべての項目の追加(I)］は使用不可になっています。［すべての項目の追加(I)］を選択する前に，アクティブなデータセットを持っているデータソースとグリッドを関連付けます。

2.	グリッドに静的な列がすでにある場合，既存の列を削除するか列の集合に追加するかを尋ねるダイアログボックスが表示されます。［はい(Y)］を選択した場合は，既存の静的な列の情報は削除され，現在のデータセットのすべての項目が項目名によりデータセットでの順序に従って挿入されます。［いいえ(N)］を選択した場合は，既存の静的な列の情報は保持され，新しい列の情報がデータセットの追加項目に基づいてデータセットに追加されます。

3.	［クローズボックス］をクリックして静的な列をグリッドに適用し，ダイアログボックスを閉じます。

静的な列を個々に作成する手順は次のとおりです。

1.	列エディタの［追加(A)］ボタンを選択します。リストボックスの列が新たに選択されます。新たに選択された列には番号とデフォルトの名前（0-TColumn など）が付きます。

2.	項目をこの新しい列と関連付けるには，オブジェクトインスペクタで FieldName プロパティを設定します。

3.	新しい列にタイトルを設定するには，オブジェクトインスペクタで Title プロパティに Caption オプションを設定します。

4.	列エディタを終了して静的な列をグリッドに適用し，ダイアログボックスを閉じます。

Deleting persistent columns1084008

グリッドの静的な列の削除は，表示したくない項目を消去する場合に使います。グリッドの静的な列を削除する手順は次のとおりです。

1.	［カラム(L)］リストボックスで削除する項目を選択します。

2.	［削除(D)］をクリックします（コンテキストメニューまたは〔Del〕を使っても列の削除ができます)。

メモ	グリッドからすべての列を削除すると，Columns.State プロパティは csDefault 状態に戻りデータセットの各項目に対して動的な列を自動的に構築します。

Arranging the order of persistent columns1084009

列を列エディタに表示する順序は列をグリッドに表示する順序と同じです。列の順序を変更するには，リストボックス内で列をドラッグアンドドロップします。

列の順序を変更する手順は次のとおりです。

1.	リストボックスの列を選択します。

2.	選択した列をリストボックスの新しい位置までドラッグします。

列の順序は，実行時の操作と同じように実際のグリッドで列をドラッグしても変えられます。

Defining a lookup list column1084010

ある列が別の参照テーブルの値をドロップダウンリストで表示できるようにするには，データセットの参照項目オブジェクトを定義しなければなりません。参照項目を作成する方法についての詳細は「項目コンポーネントの操作」を参照してください。

参照項目を定義したら， 列の ButtonStyle プロパティが cbsAuto に設定されていることを確認してください。その列のセルが編集モードになっているとグリッドは自動的にコンボボックスのようなドロップダウンボタンを表示します。ドロップダウンリストには，参照項目で定義された参照値が示されます。

Defining a pick list column1084011

選択リスト列は外観と動作が参照リスト列と同じです。違う点は選択リスト列の項目は普通の項目で，ドロップダウンリストには参照テーブルではなく列の PickList プロパティの値のリストが入っている点です。

選択リスト列を定義する手順は次のとおりです。

1.	［カラムの編集］ダイアログボックスのリストボックスの列を選択します。

2.	ButtonStyle プロパティを cbsAuto に設定します。

3.	オブジェクトインスぺクタの PickList プロパティをダブルクリックして文字列リストエディタを呼び出します。

その列のドロップダウンリストに表示したい値のリストを文字列リストエディタで入力します。選択リストにデータが入っていると列は選択リスト列になります。

メモ	通常の状態に戻すには，選択リストエディタのすべてのテキストを削除します。

Putting a button in a column1084012

列の中では通常のセルエディタの右に省略記号ボタン（［...］）を表示できます。〔Ctrl〕+〔Enter〕を押すかマウスをクリックしてグリッドの OnEditButtonClick イベントを発生させます。省略記号ボタンを使って列のデータの詳細表示ができるフォームを呼び出せます。たとえば，請求書の概要を表示するテーブルで，請求総計列に省略記号ボタンを設定してその請求書の項目や税計算方法などを表示するフォームを呼び出せます。グラフィック項目では，省略記号ボタンを使ってイメージを表示するフォームを呼び出せます。

列に省略記号ボタンを作成する手順は次のとおりです。

1.	［カラム(L)］リストボックスで列を選択します。

2.	ButtonStyle を cbsEllipsis に設定します。

3.	OnEditButtonClick イベントハンドラを記述します。

Setting column properties at design time1084013

列プロパティはその列のセルにデータを表示する方法を決めます。列プロパティのほとんどは，別のコンポーネントと関連付けられているプロパティ，つまりグリッドや関連項目コンポーネントなどのデフォルトソースと呼ばれるプロパティから値をデフォルト値として取得します。

列のプロパティを設定する手順は次のとおりです。

1.	列エディタで列を選択します。

2.	そのプロパティをオブジェクトインスペクタで設定します。

表に，設定できるキー列プロパティを示します。

プロパティ	用途
位置合わせ （Alignment）	列の項目データを左揃え，右揃え，あるいは中央揃えにする。デフォルトのソースは TField.Alignment である
ボタンのスタイル （ButtonStyle）	cbsAuto の場合（デフォルト），関連付けられている項目が参照項目であったり，列の PickList プロパティにデータが入っている場合にドロップダウンリストを表示する cbsEllipsis の場合，セルの右に省略記号ボタン（［...］）を表示する。このボタンをクリックするとグリッドの OnEditButtonClick イベントが発生する cbsNone の場合，列は通常の編集コントロールを使って列のデータを編集する
色 （Color）	列のセルの背景色を指定する。テキストの前景色については，フォントプロパティを参照。デフォルトのソースは TDBGrid.Color である
選択リストの高さ （DropDownRows）	ドロップダウンリストに表示するテキストの行数。デフォルトは 7 である
項目名 （FieldName）	この列と関連付けられている項目名を指定する。空白のままでもよい
フォント （Font）	列にテキストを表示するために使うフォントの種類，サイズ，色を指定する。デフォルトのソースは TDBGrid.Font である
IME の入力モード (ImeMode)	項目を選択したときに IME の入力モードが自動的にここで指定したものに切り換わる
IME の種類 (ImeName)	使用する IME の種類を指定する。デフォルトでは何も設定されませんが，これはユーザー環境で通常使用されている IME を使用することを意味する
選択リスト （PickList）	列のドロップダウンリストに表示する値のリストを含む
書き込み禁止 （ReadOnly）	True の場合，ユーザーは列のデータを編集できない False の場合（デフォルト），列のデータを編集できる
タイトル （Title）	選択した列のタイトルのプロパティを設定する
幅 （Width）	画面ピクセルで列幅を指定する。デフォルトのソースは TField.DisplayWidth から派生する
表に，Title プロパティで設定できるオプションを示します。

プロパティ	用途
位置合わせ （Alignment）	列タイトルのキャプションテキストを左揃え（デフォルト），右揃え，あるいは中央揃えにする
キャプション （Caption）	列タイトルに表示するテキストを指定する。デフォルトのソースは TField.DisplayLabel である
色 （Color）	列のタイトルセルを描くのに使う背景色を指定する。デフォルトのソースは TDBGrid.FixedColor である
フォント （Font）	列タイトルにテキストを描くのに使うフォントの種類，サイズ，色を指定する。デフォルトのソースは TDBGrid.TitleFont である
Restoring default values to a column1084014

1 つまたは複数の列に対して加えたプロパティの変更は元に戻せます。列エディタで戻す対象の列を選択し（複数の選択も可），コンテキストメニューから［デフォルトに戻す(S)］を選択します。これを選択すると，代入されたプロパティ設定が破棄され，列のプロパティがその基になる項目コンポーネントからのプロパティに戻されます。


Setting grid options
Setting grid options1084015

Section topics 	参照

設計時にグリッドの Options プロパティを使って実行時の基本的なグリッドの動作と外観を制御できます。設計時に初めてグリッドコンポーネントをフォームに配置すると，オブジェクトインスペクタの Options プロパティが +（正符号）付きで表示されます。これは Options プロパティを展開して個別に設定できる一連の論理型プロパティを表示できることを示します。

これらの論理型プロパティを表示して設定するには，Options プロパティをダブルクリックします。設定できるオプションのリストが Options プロパティの下のオブジェクトインスペクタに表示されます。+（正符号）は -（負符号）に変わり，Options プロパティをダブルクリックすればプロパティリストを折りたためることを示します。

表に設定可能な Options プロパティの一覧と実行時にグリッドに与える影響を示します。

オプション	用途
dgEditing	True の場合（デフォルト），グリッドのレコードは編集，挿入，削除ができる False の場合，グリッドのレコードは編集，挿入，削除ができない
dgAlwaysShowEditor	True の場合，項目は選択されると編集状態になる False の場合（デフォルト），項目は選択されても自動的に編集状態にはならない
dgTitles	True の場合（デフォルト），グリッド上部の横に項目名が表示される False の場合，項目名は表示されない
dgIndicator	True の場合（デフォルト），インジケータ列がグリッドの左に表示され，現在のレコードのインジケータ（グリッド左にある矢印）はアクティブになって現在のレコードを示す。挿入では矢印はアスタリスクになる。編集では矢印は I 型になる False の場合，インジケータ列は表示されない
dgColumnResize	True の場合（デフォルト），タイトル領域の列ルーラーをドラッグして列のサイズ変更ができる。サイズ変更をすると基になる TField コンポーネントに対応して決められていた幅も変更される False の場合，グリッド内の列はサイズ変更できない
dgColLines	True の場合（デフォルト），列の間に垂直分割線を表示する False の場合，列の間に垂直分割線を表示しない
dgRowLines	True の場合（デフォルト），レコードの間に水平分割線を表示する False の場合，レコードの間に水平分割線を表示しない
dgTabs	True の場合（デフォルト），レコードの項目間をタブ移動できる False の場合，タブ移動はグリッドコントロールから抜ける
dgRowSelect	True の場合，選択バーはグリッドの幅全体に広がる False の場合（デフォルト），レコード内の項目を選択するとその項目だけが選択される
dgAlwaysShowSelection	True の場合（デフォルト），グリッドの選択バーは別のコントロールにフォーカスがあっても常に表示される False の場合，グリッドの選択バーはグリッドにフォーカスがある場合のみ表示される
dgConfirmDelete	True の場合（デフォルト），レコード削除（〔Ctrl〕+〔Del〕）の確認を行う False の場合，確認なしでレコードを削除する
dgCancelOnExit	True の場合（デフォルト），グリッドにフォーカスがある場合，挿入をキャンセルする。このオプションにより，不完全なレコードや空のレコード
dgMultiSelect	True の場合，ユーザーは次の方法でグリッド内の複数の行を選択できる 〔Shift〕+ 矢印キー 〔Ctrl〕+ マウスクリック （〔Shift〕+ クリックはサポートされていない） 選択された行は TBookMarkList オブジェクト内のブックマーク文字列として管理される False の場合，複数の行を選択できない


Editing in the grid
Editing in the grid1084016

Section topics 	参照

以下の条件（デフォルト）を満たす場合，実行時にグリッドを使って既存のデータを変更したりレコードを新しく入力できます。

Dataset の CanModify プロパティが True である

グリッドの ReadOnly プロパティが False である

グリッド内でレコードを編集する場合，各項目に対して行った変更はレコードバッファに記録されます。ただし，ユーザーがグリッド内の別のレコードに移動しない限り，この動作は起こりません。レコードを登録するとき，そのデータセットに関連付けられているすべてのデータベース対応コンポーネントの状態の変化がチェックされます。変更データを含む項目の更新に問題がある場合は，例外が生成されてレコードは変更されま
せん。

別のレコードに移動する前にいずれかの項目で〔Esc〕を押すと，レコードの編集内容をすべて取り消せます。


Rearranging column order at design time
Rearranging column order at design time1084017

Section topics 	参照

静的な列を持っているグリッドコントロールや，データセットに静的な項目が含まれるようなデフォルトのグリッドでは，設計時に列のタイトルセルをクリックしてグリッドの新しい位置までドラッグするとグリッド列の順序を変えられます。

メモ	項目エディタで静的な項目の順序を変えてもデフォルトグリッドの列の順序は変わりますが，カスタムグリッドの列の順序は変わりません。

重要	設計時に動的な列と動的な項目の両方を持つようなグリッドの列の順序は変えられません。変更された項目や列の順序を記録する静的なものは何もないからです。


Rearranging column order at run time
Rearranging column order at run time1084018

Section topics 	参照

列の DragMode プロパティが dmManual に設定されていれば，実行時にユーザーはマウスでその列をドラッグしてグリッド内の位置を変更できます。csDefault 状態の Columns.State プロパティを使ってグリッドの列の順序を変えても，グリッドの基になるデータセットの項目コンポーネントの順序が変わります。物理テーブルの項目の順序は変わりません。

列が移動した後，グリッドの OnColumnMoved イベントが発生します。

実行時にユーザーが列の順序を変えられなくするには，グリッドの DragMode プロパティを dmAutomatic に設定します。


Controlling grid drawing
Controlling grid drawing1084019

Section topics 	参照

グリッドコントロールの描画方法を制御する最初のレベルとして列のプロパティを設定します。グリッドは自動的に列のフォント，色，位置合わせの各プロパティを使ってその列のセルを描きます。データ項目に入るテキストはその列に関連付けられた項目コンポーネントの DisplayFormat プロパティか EditFormat プロパティを使って描かれます。

グリッドの OnDrawColumnCell イベントのコードを使ってデフォルトのグリッドの表示コードを拡張できます。グリッドの DefaultDrawing プロパティが True の場合，イベントハンドラ OnDrawColumnCell が呼び出される前に通常のすべての描画が実行されます。デフォルトの表示以外にもコードで描画ができます。これは主に空白の静的な列を定義してその列のセルに特殊なグラフィックを描きたい場合に使います。

グリッドの描画方法全体を置換したい場合，DefaultDrawing の設定を False にし，グリッドの OnDrawColumnCell イベントに描画コードを入れます。一部の列や項目データ型に限って描画方法を置換したい場合は，イベントハンドラ OnDrawColumnCell の内部で DefaultDrawColumnCell を呼び出して，グリッドが選択列で通常の描画コードを使うようにします。たとえば論理項目型の描画方法を変えたいだけの場合にはこの方法を使うと作業量が少なくなります。


Responding to user actions at run time
Responding to user actions at run time1084020

Section topics 	参照

グリッド内部の特定の動作に反応するイベントハンドラを記述すれば，実行時のグリッドの動作を変更できます。グリッドの特徴は一度に多数の項目やレコードを表示することなので，個々の列が変更されるとその変更に細かく対応する必要が出てきます。たとえば，ユーザーがある列を入力したり終了するたびにフォーム上のどこか別の場所のボタンをアクティブにしたり非アクティブにしたい場合があります。

表にオブジェクトインスペクタで使用可能なグリッドイベントを示します。

イベント	用途
OnCellClick	ユーザーがグリッドのセルをクリックしたときに行う動作を指定する
OnColEnter	ユーザーがグリッドの列に入ったときに行う動作を指定する
OnColExit	ユーザーがグリッドの列から離れたときに行う動作を指定する
OnColumnMoved	ユーザーが列を新しい位置に移動したときに呼び出される
OnDblClick	ユーザーがグリッド内でダブルクリックしたときに行う動作を指定する
OnDragDrop	ユーザーがグリッド内でドラッグアンドドロップしたときに行う動作を指定する
OnDragOver	ユーザーがグリッドをドラッグオーバーしたときに行う動作を指定する
OnDrawColumnCell	個々のセルを描くために呼び出される
OnDrawDataCell	（廃止）State が csDefault になっているグリッドで呼び出され，個々のセルを描く
OnEditButtonClick	ユーザーが列の省略記号ボタンをクリックしたとき呼び出される
OnEndDrag	ユーザーがグリッドでドラッグをやめたときに行う動作を指定する
OnEnter	グリッドにフォーカスが移ったときの動作を指定する
OnExit	グリッドがフォーカスを失ったときの動作を指定する
OnKeyDown	グリッド上でユーザーがいずれかのキー（またはキーの組み合わせ）を押したときに行う動作を指定する
OnKeyPress	グリッド上でユーザーがどれか 1 つの英数字キーを押したときに行う動作を指定する
OnKeyUp	グリッド上でユーザーがキーを放したときの動作を指定する
OnStartDrag	ユーザーがグリッド上でドラッグを開始したときの動作を指定する
OnTitleCClick	ユーザーが列のタイトルをクリックしたときに行う動作を指定する
これらのイベントには多くの用途があります。たとえば，OnDblClick イベント用にハンドラを記述して，ユーザーが列に入力する値を選択できるリストをポップアップすることができます。このようなハンドラは SelectedField プロパティを使って現在の行と列を決めます。


Creating a grid that contains other data-aware controls
Creating a grid that contains other data-aware controls1084021

Section topics 	参照

TDBCtrlGrid コントロールは複数のレコードの複数の項目を表形式のグリッドに表示します。グリッドの個々のセルは単一の行から複数の項目を表示します。

データベースコントロールグリッドを使う手順は次のとおりです。

1.	データベースコントロールグリッドをフォーム上に入れます。

2.	グリッドの DataSource プロパティをデータソースの名前に設定します。

3.	グリッドの設計セル内部に個々のデータコントロールを入れます。グリッドの設計セルはグリッドの一番上か左のセルのことで，ほかのコントロールを配置できる唯一のセルです。

4.	個々のデータコントロールの DataField プロパティを項目の名前に設定します。これらのデータコントロールのデータソースは，データベースコントロールグリッドのデータソースに設定済みです。

5.	セル内部でコントロールを希望どおりに並べ替えます。

データベースコントロールグリッドを含むアプリケーションをコンパイルして実行するときには，実行時に設計セルに設定したデータコントロールの配置がグリッドの各セルに複製されます。個々のセルはデータセット内の異なるレコードを表示します。

設計時の TDBCtrlGrid

表に設計時に設定できる特有なデータベースコントロールグリッドプロパティを一部示します。

プロパティ	用途
AllowDelete	True の場合（デフォルト），レコードの削除を許す False の場合，レコードの削除を許さない
AllowInsert	True の場合（デフォルト），レコードの挿入を許す False の場合，レコードの挿入を許さない
ColCount	グリッド内の列数を設定する。デフォルトは 1 である
Orientation	goVertical 左から右，一番右まで行ったら，ひとつ下の左から右 goHorizontal 上から下，一番下まで行ったら，ひとつ右の上から下
PanelHeight	個々のパネルの高さを設定する。デフォルトは 72 である
PanelWidth	個々のパネルの幅を設定する。デフォルトは 200 である
RowCount	表示するパネル数を設定する。デフォルトは 3 である
ShowFocus	True の場合（デフォルト），実行時に現在のレコードのパネルの周囲にフォーカスの四角形を表示する False の場合，フォーカスの四角形を表示しない


See also1084022

TDBGrid

TDBCtrlGrid

データコントロールの使い方

項目コンポーネントの操作


Using decision support components
Using decision support components1085001

Section topics	参照

デシジョン（意思決定支援）コンポーネントを使うと，クロス集計の表やグラフを簡単に作成できます。これらの表やグラフを使えば，何通りもの観点からデータの表示や集計ができます。データのクロス集計についての詳細は，「クロス集計について」を参照してください。

デシジョンコンポーネントはデシジョンキューブパレットに表示されます。

デシジョンキューブ TDecisionCube は多次元のデータストアである

デシジョンソース TDecisionSource はデシジョングリッドまたはデシジョングラフの現在のピボット状態を定義する

デシジョンクエリー TDecisionQuery はデシジョンキューブでデータの定義に使う TQuery の特殊な形式である

デシジョンピボット TDecisionPivot のボタンを押して，デシジョンキューブの各次元（項目）を開く，または閉じる

デシジョングリッド TDecisionGrid は単次元と多次元のデータを表形式で表示する

デシジョングラフ TDecisionGraph はデシジョングリッドの項目を動的グラフとして表示する。このグラフはデータの次元が変更されるとそれに応じて変化する

図に，すべてのデシジョンコンポーネントがフォーム上に設計時にどのように配置されているかを示します。1085002


About crosstabs
About crosstabs1085003

Section topics	参照

クロス集計は，データの部分集合を互いの関係や傾向がよくわかるように表す方法です。クロス集計では表の項目が次元に相当し，項目値は同一次元内のカテゴリと集計を定義します。

デシジョンコンポーネントを使うとフォーム内にクロス集計を設定できます。TDecisionGrid はデータを表形式で示し，TDecisionGraph はグラフ形式で示します。TDecisionPivot のボタンを押すと次元の表示／非表示，列や行間の次元の移動が簡単にできます。

クロス集計は単次元でも多次元でも可能です。

One-dimensional crosstabs1085004

単次元クロス集計は，1 つの次元のカテゴリ別集計行（または列）を示します。たとえば，Payment を列次元，Amount Paid を集計カテゴリとすると，図のクロス集計は各観点で支払い額を示します。1085005

Multidimensional crosstabs1085006

多次元クロス集計は行または列に複数の次元を使います。たとえば，2 次元クロス集計では，各国の支払い方法に従って支払い額を表示できます。

3 次元クロス集計は，図に示すように，各国の支払い方法と支払い条件に従って支払い額を表示できます。1085007


Guidelines for using decision support components
Guidelines for using decision support components1085008

Section topics	参照

「デシジョンコンポーネントの使い方」に示すデシジョンコンポーネントは，多次元データを表やグラフとして表すのに使えます。データセットごとに複数の表やグラフを結合できます。また，TDecisionPivot の複数のインスタンスを使うと，実行時にさまざまな観点からデータを表示できます。

多次元データの表やグラフを含むフォームを作成する手順は次のとおりです。

1.	フォームを作成します。

2.	以下のコンポーネントをフォームに追加し，オブジェクトインスペクタを使って以下のとおりに結合します。

データセット。通常は TDecisionQuery（詳細は「TDecisionQuery を使ったデシジョンデータセットの作成」を参照）または TQuery

デシジョンキューブ TDecisionCube。DataSet プロパティにデータセット名を設定してそのデータセットに結合する

デシジョンソース TDecisionSource。DecisionCube プロパティにデシジョンキューブの名前を設定してそのデシジョンキューブに結合する

3.	デシジョンピボット TDecisionPivot を追加し，オブジェクトインスペクタで DecisionSource プロパティに適切なデシジョンソース名を設定して，そのデシジョンソースに結合します。デシジョンピボットは省略できますが使うと便利です。たとえばフォーム開発者やエンドユーザーはデシジョンピボットのボタンを押すだけで，デシジョングリッドやデシジョングラフに表示する次元を変更できます。

デフォルトの方向（水平方向）では，デシジョンピボットの左側のボタンがデシジョングリッドの左端の項目（行）を制御し，右側のボタンがデシジョングリッドの上端の項目（列）を制御します。

デシジョンピボットのボタンの表示位置を指定するには，その GroupLayout プロパティを xtVertical，xtLeftTop，xtHorizontal（デフォルト）のいずれかに設定します。デシジョンピボットのプロパティについての詳細は，「デシジョンピボットの使い方」を参照してください。

4.	1 つまたは複数のデシジョングリッドとデシジョングラフを追加し，デシジョンソースに結合します。詳細は「デシジョングリッドの作成と使い方」と「デシジョングラフの作成と使い方」を参照してください。

5.	デシジョンクエリーエディタを使うか TDecisionQuery（または TQuery）の SQL プロパティを使って，グリッドまたはグラフに表示するテーブル，項目，集計を指定します。SQL SELECT の最後の項目は集計項目でなければなりません。SELECT の残りの項目は GROUP BY 項目でなければなりません。詳細は「TDecisionQuery を使ったデシジョンデータセットの作成」を参照してください。

6.	デシジョンクエリー（またはかわりのデータセットコンポーネント）の Active プロパティを True に設定します。

7.	デシジョングリッドとデシジョングラフを使って，さまざまな次元のデータを表形式とグラフ形式で表示します。詳細とヒントは，「デシジョングリッドの使い方」と「デシジョングラフの使い方」を参照してください。

フォーム上のすべてのデシジョンコンポーネントについては，「デシジョンコンポーネントの使い方」の図を参照してください。


Using datasets with decision support components
Using datasets with decision support components1085009

Section topics	参照

データセットに直接結合するデシジョンコンポーネントは，デシジョンキューブ TDecisionCube だけです。TDecisionCube は，許容できる形式の SQL 文で定義されたグループおよび集計のデータを受け取ることを想定しています。GROUP BY 句には SELECT 句と同じ非集計項目が同じ順序で入っていなければならず，集計項目は識別されている必要があります。

デシジョンクエリーコンポーネントTDecisionQuery は TQuery の特殊な形式です。このコンポーネントを使うと，デシジョンキューブ TDecisionCube にデータを割り当てるのに使う次元（行と列）と集計値の設定をより簡単に定義できます。通常の TQuery などのデータセットも TDecisionCube 用のデータセットとして使えますが，その場合は設計者がデータセットと TDecisionCube を自分で適切に設定しなければなりません。

デシジョンキューブを正しく操作するには，データセット内のすべての設計項目を次元または集計にしなければなりません。集計は累積値（合計または件数など）であり，次元値の組み合わせごとの合計を表します。設定をできるだけ簡単にするには，データセットで合計には「Sum...」，件数には「Count...」という名前を付けます。


Creating decision datasets with TQuery or TTable
Creating decision datasets with TQuery or TTable1085010

Section topics	参照

通常の TQuery コンポーネントをデシジョンデータセットとして使う場合は，必ず SELECT 句と同じ項目が同じ順序で入っている GROUP BY 句を指定するように SQL 文を自分で設定しなければなりません。

SQL の例を次に示します。

'SELECT ORDERS."Terms" , ORDERS."ShipVIA" , '

' ORDERS."PaymentMethod" , '

' sum( ORDERS."AmountPaid" )'

'FROM "ORDERS.DB" ORDERS'

'GROUP BY'

' ORDERS."Terms" , ORDERS."ShipVIA" ,

ORDERS."PaymentMethod"'

SELECT 項目の順序は GROUP BY 項目の順序と一致していなければなりません。

TTable を使って，問い合わせのうちどれがグループ化項目でどれが集計かをデシジョンキューブに指定しなければなりません。


Creating decision datasets with TDecisionQuery
Creating decision datasets with TDecisionQuery1085011

Section topics	参照

デシジョンコンポーネントが使うデータはすべてデシジョンキューブに渡され，デシジョンキューブは，SQL 問い合わせがもっとも簡単に作成できる特殊な形式のデータセットを受け付けます。詳細は「デシジョンコンポーネントでのデータセットの使い方」を参照してください。

TTable と TQuery のどちらもデシジョンデータセットとして使えますが，TDecisionQuery を使う方が簡単です。このコンポーネントと一緒に提供されるデシジョンクエリーエディタを使うと，デシジョンキューブに表示するテーブル，項目，集計を指定できるほか，SQL の SELECT 句と GROUP BY 句を正しく設定できます。

デシジョンクエリーエディタを使う手順は次のとおりです。

1.	フォームのデシジョンクエリーコンポーネントを選択します。次に右クリックし，［Decision Query Editor］を選択します。［Decision Query Editor］ダイアログボックスが表示されます。

2.	単一テーブルの問い合わせの場合は［Select Table］ボタンをクリックします。

複数テーブルの結合を含む複雑な問い合わせの場合は，［Query Builder］ボタンをクリックしてビジュアル問い合わせビルダを表示します。

3.	使いたいデータベースを選択します。

4.	使いたいテーブルを選択し，1 つのテーブル内の共通項目を指しそれを別のテーブルの同じ項目へドラッグしてテーブル同士を正しく結合します。

5.	［Decision Query Editor］ダイアログボックスに戻ります。

6.	［Decision Query Editor］ダイアログボックスの［Available Fields］リストボックスの項目を選択し，該当する右矢印ボタンをクリックしてその項目を［Dimensions］または［Summaries］に割り当てます。平均集計は［Sum］と［Count］から計算されることに注意してください。

7.	デフォルトの場合，デシジョンクエリーの SQL プロパティで定義されるすべての項目と集計は［Active Dimensions］リストボックスと［Active Summaries］リストボックスに表示されます。次元または集計を削除するには，リストでその項目を選択してリストの横にある左矢印をクリックするか，その項目をダブルクリックします。元に戻すには［Available Fields］リストボックスでその項目を選択し，該当する右矢印をクリックします。

デシジョンキューブの内容を定義したら，DimensionMap プロパティと TDecisionPivot のボタンを使って次元表示を詳細に操作できます。詳細は「デシジョンキューブの使い方」，「デシジョンソースの使い方」，「デシジョンピボットの使い方」を参照してください。


Decision query properties
Decision query properties1085012

Section topics	参照

デシジョンクエリーにはほかのコンポーネントから継承したプロパティしかありません。重要な継承プロパティは Active と SQL です。Active についてはオンラインヘルプと『ライブラリリファレンス』で TDataSet の説明を，SQL については TQuery の説明を参照してください。問い合わせについての詳細は，「問い合わせの操作」を参照してください。


Using decision cubes
Using decision cubes1085013

Section topics	参照

デシジョンキューブコンポーネント TDecisionCube はデータセットからデータを取り出す多次元のデータストアで，通常は TDecisionQuery または TQuery を経由して入力される特殊な構造の SQL 文です。データは，もう一度問い合わせを実行しなくても簡単にピボット（データの構成および集計方法）の変更が行える形式で格納されます。


Decision cube properties and events
Decision cube properties and events1085014

Section topics	参照

TDecisionCube の DimensionMap プロパティは，どの次元や集計を表示するかを制御するだけでなく，日付範囲を設定し，デシジョンキューブがサポートできる次元の最大数を指定します。設計時にデータを表示するかどうかも指定できます。名前，値（カテゴリ別），小計，データなどを表示できます。ただし設計時にデータを表示すると，データソースによっては時間がかなりかかることがあります。

オブジェクトインスペクタの DimensionMap の横にある項目をクリックすると，［Decision Cube Editor］ダイアログボックスが表示されます。このダイアログボックスのページとコントロールを使うと，DimensionMap プロパティを設定できます。

デシジョンキューブのキャッシュが再構築されるたびに，OnRefresh イベントが起動します。このとき開発者は新しい次元マップにアクセスしてそのマップを変更することにより，メモリを解放したり，集計や次元の最大数を変更したりできます。ユーザーがデシジョンキューブエディタにアクセスする場合にも OnRefresh は役立ちます。このとき，ユーザーの変更にアプリケーションコードが応答できます。


Using the Decision Cube editor
Using the Decision Cube editor1085015

Section topics	参照

デシジョンキューブエディタを使うと，デシジョンキューブの DimensionMap プロパティを設定できます。デシジョンキューブエディタは，直前の節で説明したようにオブジェクトインスペクタから表示することも，設計時にフォーム上でデシジョンキューブを右クリックしてから［Decision Cube Editor］を選択して表示することもできます。

［Decision Cube Editor］ダイアログボックスには以下の 3 つのタブがあります。

［Dimension Settings］は使用可能な次元のアクティブ／非アクティブの設定，次元の名前と形式の変更，次元の固定状態化，表示する日付範囲の設定などに使う

［Design Options］は設計時に表示する名前とデータを指定するのに使う

［Cube Capacity］は一度にアクティブにできる次元と集計の最大数を設定するのに使う。メモリの使用状況に関する情報を表示するのにも使う

Viewing and changing dimension settings1085016

次元の設定を表示するには，デシジョンキューブエディタを表示し，［Dimension Settings］タブをクリックします。次に［Available Fields］リストで次元または集計を選択します。その情報がエディタの右端にあるボックス内に表示されます。

デシジョンピボット，デシジョングリッド，デシジョングラフに表示する次元または集計の名前を変更するには，［Display Name］編集ボックスに新しい名前を入力する

選択した項目が次元か集計のどちらであるかを決定するには，［Type］編集ボックスのテキストを読む。データセットが TTable コンポーネントの場合，［Type］編集ボックスを使って，選択した項目が次元か集計かを指定できる

選択した次元または集計をアクティブまたは非アクティブにするには，［Active Type］ドロップダウンリストボックスの設定（［Active］，［As Needed］，［Inactive］）を変更する。次元を非アクティブにするか［As Needed］に設定するとメモリを節約できる

次元または集計の形式を変更するには，［Format］編集ボックスに Delphi 形式の文字列を入力する

次元または集計を年単位，四半期単位，月単位で表示するには，［Grouping］ドロップダウンリストボックスの設定を変更する。［Grouping］リストボックスで［Single Value］を選択すると，選択した次元または集計を「固定した」ままの状態にできる。このように設定すると，次元の値の数が多いときにメモリを節約できる。詳細は「デシジョンコンポーネントとメモリ制御」を参照

Viewing and changing design options1085017

設計時に表示する情報の量を指定するには，デシジョンキューブエディタを表示し，［Memory Control］タブをクリックします。次に表示したい名前とデータを示している設定にチェックマークを付けます。設計時にデータまたは項目名を表示すると，データの読み込みに時間がかかるため処理効率が低下することがあります。

Setting the maximum available dimensions and summaries1085018

選択したデシジョンキューブに結合したデシジョンピボット，デシジョングリッド，デシジョングラフで使用可能な次元と集計の最大数を指定するには，デシジョンキューブエディタを表示し，［Memory Control］タブをクリックします。必要であればスピンコントロールを使って現在の設定を調整します。これらの設定を使うと，デシジョンキューブに必要なメモリの量を制御できます。詳細は「デシジョンコンポーネントとメモリ制御」を参照してください。


Using decision sources
Using decision sources1085019

Section topics	参照

デシジョンソースコンポーネント TDecisionSource は，デシジョングリッドまたはデシジョングラフの現在のピボット状態を定義します。2 つのオブジェクトが同じデシジョンソースを使う場合，ピボット状態も同じです。


Properties and events
Properties and events1085020

Section topics	参照

デシジョンソースの外観と動作を制御する特殊なプロパティとイベントには以下のものがあります。

TDecisionSource の ControlType プロパティは，デシジョンピボットのボタンがチェックボックス（一度に複数の選択が可能）またはラジオボタン（一度に 1 つしか選択できない）のどちらの機能を持つかを示す

TDecisionSource の SparseCols プロパティと SparseRows プロパティは空の列または行を表示するかどうか示す。True ならば，空の行または列も含めて表示される

TDecisionSource のイベントは以下のとおりです。

OnLayoutChange は，データの再編成を伴うピボット移動または固定化をユーザーが実行すると発生する

OnNewDimensions は，データが完全に変更されると（集計項目または次元項目が変更される場合など）発生する

OnSummaryChange は現在の集計が変化すると発生する

OnBeforePivot は，変更内容がコミットされたがユーザーインターフェースにまだ反映されていないと発生する。開発者はアプリケーションユーザーに直前の動作結果を表示する前に，容量やピボット状態などを変更できる

OnAfterPivot はピボット状態が変化すると発生する。開発者はこのときに情報を取得できる


Using decision pivots
Using decision pivots1085021

Section topics	参照

デシジョンピボットコンポーネント TDecisionPivot のボタンを押すと，デシジョンキューブの各次元（項目）を開閉できます。TDecisionPivot ボタンを押して行または列を開くと，対応する次元が TDecisionGrid コンポーネントまたは TDecisionGraph コンポーネントに表示されます。次元を閉じると，その詳細なデータは表示されずにほかの次元の合計の中に折りたたまれます。次元は「固定」状態にもできます。この場合，次元項目の特定の値の集計だけが表示されます。

デシジョンピボットを使うと，デシジョングリッドやデシジョングラフに表示する次元の再編成もできます。再編成は，ボタンを行領域または列領域までドラッグするか，同じ領域内でボタンの順序を入れ替えるだけでできます。

設計時のデシジョンピボットについては，以下を参照してください。
デシジョンコンポーネントの使い方
クロス集計について


Properties
Properties1085022

Section topics	参照

デシジョンピボットの外観と動作を制御する特殊なプロパティには以下のものがあります。

TDecisionPivot で最初に表示されるプロパティは，全体の動作と外観を定義する。 TDecisionPivot の ButtonAutoSize を False に設定すると，コンポーネントのサイズを調整するときボタンの大きさが固定される

TDecisionPivot の Groups プロパティはどの次元ボタンを表示するかを定義する。行，列，集計の選択ボタングループはどのような組み合わせでも表示できる。これらのグループをもっと自由に配置するには，フォーム上で行だけ入っている TDecisionPivot をある位置に割り当て，次に列だけ入っている TDecisionPivot を別の位置に割り当てる

通常の場合，TDecisionPivot は TDecisionGrid の上に追加される。デフォルトの方向（水平方向）では，TDecisionPivot の左側のボタンが TDecisionGridの左端の項目（行）を制御し，右側のボタンが TDecisionGridの上端の項目（列）を制御する

TDecisionPivot のボタンの表示位置を指定するには，その GroupLayout プロパティを xtVertical，xtLeftTop，xtHorizontal（デフォルト）のいずれかに設定する（デフォルト設定については直前のパラグラフを参照）。


Creating and using decision grids
Creating and using decision grids1085023

Section topics	参照

デシジョングリッドコンポーネント TDecisionGrid はクロス集計したデータを表形式で表示します。（クロス集計の詳細は「クロス集計について」を参照してください）。「デシジョンコンポーネントの使い方」の図に，設計時のフォーム上のデシジョングリッドを示します。

  Creating decision grids1085024

クロス集計データが入った 1 つまたは複数の表を含むフォームを作成する手順は次のとおりです。

1.	「デシジョンコンポーネントの使い方」の手順 1～3 を実行します。

2.	1 つまたは複数のデシジョングリッドコンポーネント（TDecisionGrid）を追加し，デシジョンソース TDecisionSource に結合します。この場合，オブジェクトインスペクタで DecisionSource プロパティに適切なデシジョンソースコンポーネントを設定します。

3.	「デシジョンコンポーネントの使い方」の手順 5～7 を実行します。

グラフをフォームに追加するには，「デシジョングラフの作成」の手順に従います。

 Using decision grids1085025

デシジョングリッドコンポーネント TDecisionGrid は，デシジョンソース（TDecisionSource）に結合されたデシジョンキューブ（TDecisionCube）のデータを表示します。

デフォルトでは，データセットで定義されたグループ化命令に応じて，グリッドの左端と上端のどちらか一方あるいは両方に次元項目が表示されます。各項目の下にはデータ値ごとにカテゴリが 1 つずつ表示されます。このグリッドでは以下のことができます。

次元の開閉

行と列の再編成（ピボット）

詳細を表示するための固定化

次元選択の制限（軸ごとに 1 つの次元）

デシジョングリッドの特殊なプロパティとイベントについての詳細は，「デシジョングリッドのプロパティ」を参照してください。

Opening and closing decision grid fields1085026

次元項目または集計項目にプラス記号（+）が表示されている場合，その右にある 1 つまたは複数の項目は閉じています（隠れています）。プラス記号をクリックすれば，右にある項目やカテゴリを開くことができます。マイナス記号（-）が表示されている場合，その項目は完全に開いています（展開されています）。マイナス記号をクリックすると，項目が閉じます。このアウトライン機能は使用不可にできます。詳細は「デシジョングリッドのプロパティ」を参照してください。

Reorganizing rows and columns in decision grids1085027

行見出しや列見出しは，同じ軸内の新しい位置へでもほかの軸へでもドラッグできます。これにより，データのグループ化の変更に合わせて，グリッドを再編成し，新しい観点でデータを表示できます。このピボット機能は使用不可にできます。詳細は「デシジョングリッドのプロパティ」を参照してください。

デシジョンピボットを入れておけば，そのボタンを押してドラッグするだけで表示を再編成できます。詳細は「デシジョンピボットの使い方」を参照してください。

Drilling down for detail in decision grids1085028

ある次元を固定して詳細を表示できます。

たとえば，ほかの次元がその下に折りたたまれている次元のカテゴリラベル（行見出し）を右クリックすると，特定のカテゴリに固定してそのカテゴリのデータだけを表示することができます。次元を固定すると，1 つのカテゴリ値のレコードだけが表示されるため，グリッドに表示されるその次元のカテゴリラベルは表示されなくなります。フォームにデシジョンピボットを追加すると，カテゴリ値が表示されるので必要であればほかの値を変更できます。

1 つの次元に固定するには，以下の 2 通りの方法があります。

カテゴリラベルを右クリックし，［Drill In To This Value］を選択する

ピボットボタンを右クリックし，［Drilled In］を選択する

次元全体をアクティブに戻すには，次の方法があります。

対応するピボットボタンを右クリックするか，

デシジョングリッドの左上隅を右クリックしてから次元を選択する

Limiting dimension selection in decision grids1085029

デシジョングリッドの軸ごとに複数の次元を選択できるようにするかどうか指定するには，デシジョンソースの ControlType プロパティを変更します。詳細は「デシジョンソースの使い方」を参照してください。


Decision grid properties
Decision grid properties1085030

Section topics	参照

デシジョングリッドコンポーネント TDecisionGrid は，TDecisionSource に結合された TDecisionCube コンポーネントのデータを表示します。デフォルトでは，データがグリッド内に表示され，カテゴリ項目がグリッドの左端と上端に表示されます。

デシジョングリッドの外観と動作を制御する特殊なプロパティには以下のものがあります。

TDecisionGrid には次元ごとに固有のプロパティがある。これらのプロパティを設定するには，オブジェクトインスペクタで Dimensions を選択してから次元を選択する。選択した次元のプロパティがオブジェクトインスペクタに表示される。Alignment はその次元のカテゴリラベルの位置合わせを定義する。Caption を使うとデフォルトの次元名を変更できる。Color はカテゴリラベルの色を定義する。FieldName はアクティブな次元の名前を表示する。Format はそのデータ型の標準の Delphi 形式を保持できる。Subtotals はその次元の小計を表示するかどうかを指定する。集計項目では，これらと同じプロパティを使って，グリッドの集計領域に表示するデータの外観を変更する。次元プロパティの設定がすべて済んだら，フォームのコンポーネントをクリックするか，オブジェクトインスペクタの上端にあるドロップダウンリストボックスのコンポーネントを選択する

TDecisionGrid の Options プロパティを使うと，グリッド線の表示の制御（cgGridLines = True），アウトライン機能（+ 記号と - 記号を使って次元を折りたたんだり展開したりする機能）の設定（cgOutliner = True），ドラッグアンドドロップピボットの設定（cgPivotable = True）ができる

TDecisionGrid の OnDecisionDrawCell イベントを使うと，描画時に各セルの外観を変更できる。このイベントは var パラメータとして現在のセルの String，Font，Color を渡す。負の値を特殊な色で表すなどの効果が得られるように，これらの var パラメータは変更できる。TCustomGrid が渡す Drawstate のほかに，TDecisionDrawState も渡される。これはどの種類のセルを描画するか指定する。セルに関する情報は，関数 Cells，CellValueArray，CellDrawState を使って取り出せる

TDecisionGrid の OnDecisionExamineCell イベントを使うと，右クリックイベントをデータセルに関連付けることができる。このイベントは，特定のデータセルに関する情報（詳細記録など）をプログラムが表示できるようにする。ユーザーがデータセルを右クリックすると，データ値の作成に使ったすべての情報（現在アクティブな集計値など）や集計値の作成に使ったすべての次元値の ValueArray がイベントに提供される


Creating and using decision graphs
Creating and using decision graphs1085031

Section topics	参照

デシジョングラフコンポーネント TDecisionGraph は，クロス集計データをグラフ形式で表示します。デシジョングラフは 1 つの集計値（Sum，Count，Avg など）を単次元または多次元のグラフ形式で表示します。

Creating decision graphs1085032

1 つまたは複数のデシジョングラフを含むフォームを作成する手順は次のとおりです。

1.	「デシジョンコンポーネントの使い方」の手順 1～3 を実行します。

2.	1 つまたは複数のデシジョングラフコンポーネント（TDecisionGraph）を追加し，デシジョンソース TDecisionSource に結合します。この場合，オブジェクトインスペクタで DecisionSource プロパティに適切なデシジョンソースコンポーネントを設定します。

3.	「デシジョンコンポーネントの使い方」の手順 5～7 を実行します。

4.	最後にグラフを右クリックし，［Edit Chart］を選択してグラフ系列の外観を変更します。グラフ次元ごとにテンプレートプロパティを設定してから，個々の系列プロパティを設定してデフォルトを変更できます。詳細は「デシジョングラフのカスタマイズ」を参照してください。

デシジョングラフで何を表示してどのように使うかについての詳細は，「デシジョングラフの使い方」を参照してください。

Using decision graphs1085033

デシジョングラフコンポーネント TDecisionGraph は，デシジョンソース（TDecisionSource）の項目を動的グラフとして表示します。このグラフはデシジョンピボット TDecisionPivot を使ったデータ次元の開閉，ドラッグアンドドロップ，再編成に応じて変化します。

グラフ化するデータは，特殊な形式のデータセット（TDecisionQuery など）から取り出します。デシジョンコンポーネントがこのデータを処理し配置する方法については，「デシジョンコンポーネントの使い方」を参照してください。

デフォルトでは，最初の行次元は x 軸として表示され，最初の列次元は y 軸として表示されます。

デシジョングリッドではクロス集計データを表形式で表示しますが，このデシジョングリッドのかわりとして，またはデシジョングリッドと一緒にデシジョングラフを使えます。同じデシジョンソースに結合されたデシジョングリッドとデシジョングラフは同じデータ次元を表します。同じ次元についてさまざまな集計データを表示するには，複数のデシジョングラフを同じデシジョンソースに結合します。さまざまな次元を表示するには，デシジョングラフを別々のデシジョンソースに結合します。

たとえば，図 15.4 では，最初のデシジョンピボットとデシジョングラフは最初のデシジョンソースに結合され，2 番目のデシジョンピボットとデシジョングラフは 2 番目のデシジョンソースに結合されています。このようにしてグラフごとに異なる次元を表示できます。

別々のデシジョンソースに結合されたデシジョングラフ1085034

デシジョングラフに何を表示するかについての詳細は，「デシジョングラフの表示」を参照してください。

デシジョングラフの作成については，「デシジョングラフの作成」を参照してください。


The decision graph display
The decision graph display1085035

Section topics	参照

デフォルトのデシジョングラフでは，最初のアクティブな列項目の値（x 軸方向）に対して最初のアクティブな行項目のカテゴリ別の集計値（y 軸方向）がグラフ化されます。グラフ化したカテゴリは，それぞれ独立した系列として表示されます。

次元を 1 つだけ選択した場合，たとえば 1 つの TDecisionPivot ボタンだけをクリックした場合などは，1 つの系列だけがグラフ化されます。

デシジョンピボットを使う場合，そのボタンを押してどのデシジョンキューブ項目（次元）をグラフ化するか指定できます。グラフ軸を変更するには，デシジョンピボットの次元ボタンを分割スペースの一方の端から反対側の端までドラッグします。単次元グラフですべてのボタンが分割スペースの一方の端にある場合，［Row］アイコンまたは［Column］アイコンをドロップ先として使って分割スペースの反対側にボタンを追加し，多次元グラフにできます。

ある列とある行だけを同時にアクティブにするには，TDecisionSource の ControlType プロパティを xtRadio に設定します。こうすると，デシジョンキューブ軸ごとに一度にアクティブにできる項目は 1 つだけとなり，デシジョンピボットの機能がグラフの動作に対応します。xtRadioEx は xtRadio と同じ効果がありますが，すべての行またはすべての列の次元が閉じている状態にはできません。

デシジョングリッドとデシジョングラフの両方を同じ TDecisionSource に接続した場合，TDecisionGrid の動作の方が柔軟なため，それに合わせて ControlType の設定を xtCheck に戻す方がよいでしょう。


Customizing decision graphs
Customizing decision graphs1085036

Section topics	参照

デシジョングラフコンポーネント TDecisionGraph はデシジョンソース（TDecisionSource）の項目を動的グラフとして表示します。このグラフはデシジョンピボット TDecisionPivot を使ったデータ次元の開閉，ドラッグアンドドロップ，再編成に応じて変化します。デシジョングラフではその種類，色，折れ線グラフのマーカーの種類などの各種のプロパティを変更できます。

グラフをカスタマイズする手順は次のとおりです。

1.	グラフを右クリックし，［Edit Chart］を選択します。［Chart Editing］ダイアログボックスが表示されます。

2.	［Chart Editing］ダイアログボックスの［Chart］ページを使って可視系列のリストを表示し，同じ系列で複数の定義を利用できるときに使う系列定義を選択し，テンプレートまたは系列に合わせてグラフの種類を変更し，すべてのグラフプロパティを設定します。

［Chart］ページの［Series］リストには，デシジョンキューブのすべての次元（Template: が前に付いています）と現在の可視カテゴリが表示されます。カテゴリ（系列）はそれぞれ独立したオブジェクトです。以下の操作ができます。

既存のデシジョングラフ系列から派生した系列の追加または削除。派生した系列は既存の系列に注釈を与えたり，ほかの系列で計算した値を表すことができる

デフォルトのグラフの種類の変更と，テンプレートや系列のタイトルの変更

［Chart］ページのその他のタブについては，オンラインヘルプトピック「［Chart］ページ（［Chart Editing］ダイアログボックス）」を参照してください。

3.	［Series］ページを使って次元テンプレートを設定し，グラフ系列ごとにプロパティをカスタマイズします。

デフォルトでは，すべての系列が棒グラフとして表示され，最大 16 色が割り当てられます。テンプレートの種類やプロパティを編集すれば新しいデフォルトを作成できます。デシジョンソースをさまざまな状態にピボットする場合，テンプレートを使って新しい状態ごとに動的に系列を作成できます。

系列ごとのカスタマイズについては，「デシジョングラフ系列のカスタマイズ」を参照してください。

［Series］ページの各タブについては，オンラインヘルプトピック「［Series］ページ（［Chart Editing］ダイアログボックス）」を参照してください。

Setting decision graph template defaults1085037

デシジョングラフは，デシジョンキューブの 2 つの次元の値を表示します。1 つはグラフ軸として表示され，もう 1 つは系列セットの作成に使います。後者の次元のテンプレートはこれらの系列のデフォルトプロパティ（系列が棒グラフ，折れ線グラフ，面グラフなどのどれかなど）を提供します。ユーザーがある状態から別の状態にピボットすると，テンプレートで指定された系列の種類やその他のデフォルトを使って，その次元に必要な系列がすべて作成されます。

アクティブな次元が 1 つだけの状態にユーザーがピボットすると，そのたびに別のテンプレートが提供されます。単次元状態は円グラフで表されることがよくあります。この場合は別のテンプレートが提供されます。

以下の操作ができます。

グラフのデフォルトの種類の変更

グラフテンプレートのその他のプロパティの変更

グラフのすべてのプロパティの表示と設定

To change the default decision graph type:

1.	［Chart Editing］ダイアログボックスの［Chart］ページにある［Series］リストでテンプレートを選択します。

2.	［Change］ボタンをクリックします。

3.	新しい種類を選択し，［Gallery］ダイアログボックスを閉じます。

To change color or other properties of a template:1085038

1.	［Chart Editing］ダイアログボックスの上端で［Series］ページを選択します。

2.	［Series］ページの上端にあるドロップダウンリストでテンプレートを選択します。

3.	該当するプロパティタブを選択し，設定を選択します。

To view and set decision graph properties other than type and series:1085039

1.	［Chart Editing］ダイアログボックスの上端で［Chart］ページを選択します。

2.	該当するプロパティタブを選択し，設定を選択します。

Customizing decision graph series1085040

テンプレートはデシジョンキューブの次元ごとにいくつものデフォルト設定（グラフの種類，系列の表示方法など）を提供します。それ以外のデフォルト（系列の色など）は TDecisionGraph によって定義されます。必要であれば系列ごとにデフォルトを変更できます。

テンプレートは，必要になるとカテゴリの系列を作成し，不要になると破棄するようにしたい場合に使います。特定のカテゴリ値用にカスタム系列を設定することもできます。これには，グラフをピボットして，カスタマイズしたいカテゴリの系列が表示されるようにします。その系列がグラフに表示されたら，グラフエディタを使って以下の操作ができます。

グラフの種類の変更

系列のその他のプロパティの変更

カスタマイズした特定のグラフ系列の保存

系列テンプレートの定義とグラフのすべてのデフォルトの設定については，「デシジョングラフテンプレートのデフォルトを設定する」を参照してください。

Changing the series graph type1085041

デフォルトでは，各系列はその次元のテンプレートによって定義された同一のグラフの種類に設定されています。すべての系列を同じ種類のグラフに変更するには，テンプレートの種類を変更します。詳細は「デシジョングラフのデフォルトの種類を変更する」を参照してください。

1 つの系列のグラフの種類を変更する手順は次のとおりです。

1.	グラフエディタの［Chart］ページにある［Series］リストで系列を選択します。

2.	［Change］ボタンをクリックします。

3.	新しい種類を選択し，［Gallery］ダイアログボックスを閉じます。

4.	［Save Series］チェックボックスにチェックマークを付けます。

Changing other decision graph series properties1085042

デシジョングラフ系列のその他のプロパティ（色など）を変更する手順は次のとおりです。

1.	［Chart Editing］ダイアログボックスの上端で［Series］ページを選択します。

2.	［Series］ページの上端にあるドロップダウンリストで系列を選択します。

3.	該当するプロパティタブを選択し，設定を選択します。

4.	［Save Series］チェックボックスにチェックマークを付けます。

Saving decision graph series settings1085043

デフォルトでは，設計時にはテンプレートの設定だけが保存されます。［Chart Editing］ダイアログボックスで特定の系列の［Save］ボックスにチェックマークを付けると，その系列の変更内容だけが保存されます。

系列を保存するとメモリが多量に必要になります。したがって，保存の必要がない場合は［Save］ボックスのチェックマークははずします。


Decision support components at runtime
Decision support components at runtime1085044

Section topics	参照

ユーザーは実行時に，可視デシジョンコンポーネントのクリック，右クリック，ドラッグにより多様な操作ができます。これらの操作についてはこの章の始めの方で説明しましたが，要約すると以下のようになります。

Decision pivots at runtime1085045

ユーザーができる操作は以下のとおりです。

デシジョンピボットの左端にある集計ボタンをクリックして，使用可能な集計のリストを表示する。このリストを使うと，デシジョングリッドやデシジョングラフに表示する集計データを変更できる

次元ボタンを右クリックし，以下のどちらかを選択する

［Move］（データを行領域と列領域の間で移動する）

［Drill In］（対象を固定して詳細データを表示する）

［Drill In］コマンドの実行後に次元ボタンをクリックし，以下のいずれかを選択する

［Open Dimension］（その次元の最上位に戻る）

［All Values］（デシジョングリッドの集計だけを表示するか，集計とそれ以外のすべての値を表示するか切り替える）

詳細値を表示するために固定するカテゴリ（その次元で使用可能なカテゴリのリストから選択する）

次元ボタンをクリックして，その次元を開閉する

次元ボタンを行領域と列領域の間でドラッグアンドドロップする。同じ領域の既存ボタンの横にドロップしたり，行アイコンまたは列アイコンにドロップすることもできる

 Decision grids at runtime1085046

ユーザーが実行できる操作は以下のとおりです。

デシジョングリッド内を右クリックし，以下のいずれかを選択する

個々のデータグループ，ある次元のすべての値，グリッド全体の小計の設定／解除を切り替える

デシジョンキューブエディタを表示する（「デシジョンキューブエディタの使い方」を参照）

次元と集計の開閉を切り替える

行見出しと列見出し内で + と - をクリックして次元を開閉する

次元を行と列の間でドラッグアンドドロップする

 Decision graphs at runtime1085047

ユーザーはグラフのグリッド領域を上下左右にドラッグして，画面に表示されていないカテゴリや値をスクロールできます。


Decision support components and memory control
Decision support components and memory control1085048

Section topics	参照

次元または集計をデシジョンキューブにロードすると，メモリを消費します。集計を新たに追加すると，メモリの使用量は比例的に増加します。つまり，デシジョンキューブでは集計が 1 つだけのときと比べ，集計が 2 つになるとメモリの消費量は 2 倍になり，集計が 3 つになるとメモリの消費量は 3 倍になるという具合に増加していきます。

次元に対するメモリの消費量はもっと急激に増加していきます。値が 10 個の次元を追加するとメモリの消費量は 10 倍になり，値が 100 個の次元を追加するとメモリの消費量は 100 倍になります。このように次元をデシジョンキューブに追加すると，メモリの使用量に大きな影響を及ぼすため，処理効率が急激に低下することがあります。値の数が多い次元を追加した場合，この影響は顕著です。

デシジョンコンポーネントには，メモリの使用方法や使用条件を制御するのに役立つ設定がいくつも用意されています。ここで取り上げたプロパティと制御方法についての詳細は，『ライブラリリファレンス』とオンラインヘルプで TDecisionCube の説明を参照してください。1085049


Setting maximum dimensions, summaries, and cells
Setting maximum dimensions, summaries, and cells1085050

Section topics	参照

デシジョンキューブの MaxDimensions プロパティと MaxSummaries プロパティを CubeDim.ActiveType プロパティと一緒に使うと，一度にロードできる次元や集計の数を制御できます。デシジョンキューブエディタの［Cube Capacity］ページで値の最大数を設定すると，一度に何個の次元または集計をメモリにロードできるか全体的に制御できます。

次元や集計の数を制限すると，デシジョンキューブに必要なメモリ量をおおまかに制限できます。ただし，値の数が多い次元と値の数が少ない次元の区別はできません。キューブ内のセル数も制限すると，デシジョンキューブで必要なメモリの絶対量をより厳密に制御できます。セルの最大数は，デシジョンキューブエディタの［Cube Capacity］ページで設定します。


Setting dimension state
Setting dimension state1085051

Section topics	参照

ActiveType プロパティは，ロードする次元を制御します。このプロパティは，デシジョンキューブエディタの［Dimension Settings］タブで［Active Type］コントロールを使って設定できます。このコントロールを［Active］に設定すると，次元は無条件にロードされ，常にメモリ空間を占めることになります。

この状態にある次元の数は MaxDimensions の値より小さくなければなりません。また，［Active］に設定する集計の数は MaxSummaries の数より小さくなければなりません。次元または集計を［Active］に設定するのは，その次元または集計を常時使えなければならないときだけです。［Active］に設定すると，使用可能なメモリをキューブが管理する能力が低下します。

［Active Type］を［As Needed］に設定すると，MaxDimensions，MaxSummaries，または MaxCells の制限を超えないでロードできるときだけ，次元または集計がロードされます。デシジョンキューブは MaxCells，MaxDimensions，MaxSummaries によって指定された制限内に保つために，［As Needed］に設定された次元または集計をメモリに入れたりメモから出したりします。したがって，次元または集計はそのときに使われていないと，メモリにロードされていないことがあります。使用頻度が低い次元を［As Needed］に設定すれば，ロードやピボットの処理効率が上がります。ただし，現在ロードされていない次元へのアクセス時間は遅くなります。


Using paged dimensions
Using paged dimensions1085052

Section topics	参照

デシジョンキューブエディタの［Dimension Settings］タブで［Binning］を［Set］に設定したときに，［Start Value］がヌル以外の場合，次元は「ページングされている」，つまり「固定されたままの状態である」とみなされます。この場合，一度にアクセスできるのはその次元の 1 つの値のデータだけですが，プログラムで記述すれば一連の値にシーケンシャルにアクセスできます。このような次元はピボットしたり開いたりできません。

値の数が膨大な次元のデータをロードすると多量のメモリが必要になります。このような次元はページングすれば，一度に 1 つの値の集計情報を表示できます。通常はこのように表示した方が情報は読みとりやすくなり，メモリの消費量の管理も容易になります。


See also1085053

TDecisionCube

TDecisionQuery

TDecisionSource

TDecisionPivot

TDecisionGraph

TDecisionGrid

TTable

デシジョンキューブコンポーネント


Copying data and table structures
Copying data and table structures1099001

Section topics 	参照

この章では，データベースアプリケーション内での TBatchMove データセットコンポーネントの使い方について説明します。TBatchMove は，データセットの複製，一方のデータセットから別のデータセットへのレコードの追加，一方のデータセットのレコードによる別のデータセットのレコードの更新，別のデータセットのレコードに一致する一方のデータセットのレコードの削除ができるボーランドデータベースエンジン（BDE）の各機能をカプセル化します。TBatchMove は以下の場合にもっともよく使われます。

分析やその他の処理のためにサーバーからローカルデータソースにデータをダウンロードする

アップサイジング処理の一環としてデスクトップのデータベースをリモートサーバーのテーブルへ移行する。

バッチ移動コンポーネントはソーステーブルに対応する転送先テーブルを作成でき，その際に列名とデータ型を自動的にマッピングします。


Creating a batch move component
Creatinga batch move component1099002

Section topics 	参照

バッチ移動コンポーネントを作成する手順は次のとおりです。

1.	テーブルコンポーネントまたは問い合わせコンポーネントを，フォームまたはデータモジュール上に置きます。これを，インポートするデータのあるデータセット（ソースデータセット）とします。

2.	データセットコンポーネントをフォームまたはデータモジュール上に置きます。これをレコードの転送先データセットとします。

3.	コンポーネントパレットの［Data Access］ページにある TBatchMove コンポーネントをデータモジュールまたはフォーム上に置き，その Name プロパティをアプリケーションに適したユニークな値に設定します。

4.	バッチ移動コンポーネントの Source プロパティをコピー元，追加元，または更新元のテーブルの名前に設定します。テーブルは利用可能なデータセットコンポーネントのドロップダウンリストから選択できます。

5.	Destination プロパティを転送先のテーブルあるいは作成または更新するテーブルの名前に設定します。転送先テーブルは利用可能なデータセットコンポーネントのドロップダウンリストから選択できます。また，転送先テーブルとしてテーブルコンポーネントを新たに追加することもできます。

追加，更新，削除の場合，Destination プロパティは既存のテーブルの名前でなければなりません。

テーブルのコピーで Destination が既存のテーブル名になっている場合，バッチ移動を実行すると，転送先テーブル内の現在のデータがすべて上書きされます。

既存のテーブルをコピーしてまったく新しいテーブルを作成する場合，作成されるテーブルには，コピー先のテーブルコンポーネントの Name プロパティに指定されている名前が付きます。作成されるテーブルの種類は，DatabaseName プロパティで指定したサーバーに適した構造の種類になります。

6.	Mode プロパティを実行操作の種類を示すように設定します。有効な操作は，batAppend（デフォルト），batUpdate，batAppendUpdate，batCopy，batDelete のいずれかです。これらのモードについては，「バッチ移動モードの指定」を参照してください。

7.	必要であれば Transliterate プロパティを設定します。Transliterate が True（デフォルト）の場合，文字データは，必要であれば Source データセットの文字セットから Destination データセットの文字セットへ変換されます。

8.	必要であれば列のマッピングを Mappings プロパティで設定します。ソーステーブルと転送先テーブルでの位置に基づいて列がバッチ移動で照合される場合は，このプロパティを設定する必要がありません。列のマッピングについては，「データ型のマッピング」を参照してください。

9.	必要であれば ChangedTableName，KeyViolTableName，ProblemTableName の各プロパティを指定します。バッチ移動処理中に検出された問題のあるレコードが，ProblemTableName で指定したテーブルに格納されます。バッチ移動により Paradox テーブルを更新している場合は，KeyViolTableName で指定したテーブルにキー違反を報告できます。ChangedTableName には，バッチ移動処理の結果，転送先テーブルで変更があったすべてのレコードが示されます。これらのプロパティを指定しないと，以上のエラーテーブルは作成されることも使われることもありません。バッチ移動エラーの処理についての詳細は，「バッチ移動エラーの処理」を参照してください。


Specifying a batch move mode
Specifying a batch move mode1099003

Section topics 	参照

Mode プロパティはバッチ移動コンポーネントが実行する処理を指定します。

プロパティ	用途
batAppend	転送先テーブルにレコードを追加する
batUpdate	ソーステーブルのレコードで対応する転送先テーブルのレコードを更新する。更新は転送先テーブルのインデックスに基づいて行われる
batAppendUpdate	一致するレコードが転送先テーブルに存在する場合は，それを更新する。存在しない場合は，レコードを転送先テーブルに追加する
batCopy	ソーステーブルの構造に基づき転送先テーブルを作成する。転送先テーブルがすでにある場合，そのテーブルは削除され，新たに作成される
batDelete	ソーステーブルのレコードに一致する転送先テーブルのレコードを削除する


Appending
Appending1099004

Section topics 	参照

データを追加および更新するには，ターゲットデータセットがすでに存在していなければなりません。追加処理では，必要であればターゲットデータセットに適したデータ型とデータサイズにデータが変換されます。変換できない場合，例外が生成され，データは追加されません。


Updating
Updating1099005

Section topics 	参照

データを更新するには，ターゲットデータセットがすでに存在していなければならず，レコードを照合できるインデックスが定義されていなければなりません。一次インデックスフィールドを照合に使う場合，ソースデータセット内のレコードのインデックスフィールドに一致するインデックスフィールドを持つターゲットデータセット内のレコードが，ソースデータで上書きされます。更新処理では，必要であればターゲットデータセットに適したデータ型とデータサイズにデータが変換されます。


Appending and updating
Appending and updating1099006

Section topics 	参照

データを更新するには，ターゲットデータセットがすでに存在していなければならず，レコードを照合できるインデックスが定義されていなければなりません。一次インデックスフィールドを照合に使う場合，ソースデータセット内のレコードのインデックスフィールドに一致するインデックスフィールドを持つターゲットデータセット内のレコードが，ソースデータで上書きされます。一致するレコードがターゲットデータセットにない場合は，ソースデータセットのデータがターゲットデータセットに追加されます。追加更新処理では，必要であればターゲットデータセットに適したデータ型とデータサイズにデータが変換されます。


Copying
Copying1099007

Section topics 	参照

ソースデータセットのコピーを作成するには，ターゲットデータセットが存在していてはなりません。存在している場合にバッチ移動処理を行うと，既存のターゲットデータセットがソースデータセットのコピーで上書きされます。

ソースおよびターゲットのデータセットによって使用しているデータベースエンジンが異なる場合（たとえば，Paradox と InterBase など），可能な限りソースデータセットに近い構造を持つターゲットデータセットが作成され，必要であれば自動的にデータ型とデータサイズの変換が実行されます。

メモ	TBatchMove では，インデックス，制約（constraint），ストアドプロシージャなどのメタデータ構造はコピーされません。したがって，メタデータオブジェクトはサーバー上で作成しなければなりません。


Deleting
Deleting1099008

Section topics 	参照

ターゲットデータセット内のデータを削除するには，そのデータセットがすでに存在していなければならず，レコードを照合できるインデックスが定義されていなければなりません。一次インデックスフィールドを照合に使う場合，ソースデータセット内のインデックスフィールドのレコードと一致するインデックスフィールドを持つターゲットデータセット内のレコードが，転送先テーブル内で削除されます。


Mapping data types
Mapping data types1099009

Section topics 	参照

batAppendでは，バッチ移動コンポーネントはソーステーブルの列のデータ型に基づいて転送先テーブルを作成します。列と型は，ソーステーブルと転送先テーブルでの位置に基づいて照合されます。つまり，ソーステーブルの最初の列は転送先テーブルの最初の列に照合され，ほかの列も同様に照合されます。

デフォルトの列マッピングを変更するには，Mappings プロパティを使います。Mappings プロパティは，列マッピングのリスト（1 行に 1 つずつ）です。このリストは 2 つの形式のどちらかで示されます。ソーステーブルの列を転送先テーブルの同じ名前の列にマッピングするには，一致する列名を指定する単純なリストを使えます。たとえば，次のマッピングはソーステーブルの ColName という列が転送先テーブルの同じ名前の列にマッピングするように指定しています。

ColName

ソーステーブルの SourceColName という列を転送先テーブルの DestColName という名前の列にマッピングするには，次のような構文になります。

DestColName = SourceColName

ソースとターゲットの列のデータの型が同一でない場合，バッチ移動処理は「最適なもの」を試します。必要であれば文字データ型を切り詰め，可能な場合には制限付きで変換を実行しようとします。たとえば，CHAR(10) 列を CHAR(5) 列へマッピングすると，ソースの列で最後の 5 文字が切り詰められます。

変換の例として，文字データ型のソース列を整数型のターゲット列へマッピングした場合を考えます。バッチ移動処理では，文字値の「5」が対応する整数値に変換されます。値を変換できないとエラーになります。エラーについての詳細は，「バッチ移動エラーの処理」を参照してください。

異なるテーブル型の間でデータを移動する場合，バッチ移動コンポーネントはデータ型をデータセットのサーバーのタイプに基づいて適切に変換します。種類の異なるサーバー相互のマッピングに関する最新の表については，BDE のヘルプを参照してください。

メモ	SQL サーバーデータベースへのデータのバッチ移動には，データベースサーバーと，適切な SQL Link がインストールされた Delphi Client/Server Suite が必要です。サードパーティの ODBC ドライバを適切にインストールしていれば，ODBC を使用できます。


Executing a batch move
Executing a batch move1099010

Section topics 	参照

実行時にバッチ処理を実行するには，Execute メソッドを使います。たとえば，バッチ移動コンポーネントの名前が BatchMoveAdd の場合，次の文でバッチ処理を実行します。

BatchMoveAdd.Execute;

設計時には，バッチ移動コンポーネントを右クリックしてコンテキストメニューから［Execute］を選択すれば，やはりバッチ移動を実行できます。

MoveCount プロパティは，バッチ移動の実行時に移動されたレコードの件数を記録します。

RecordCount プロパティは，移動するレコードの最大数を指定します。RecordCount が 0 の場合，ソースデータセット内の最初のレコードから始まって，すべてのレコードが移動されます。RecordCount が正の数の場合，ソースデータセット内の現在のレコードから始まって，最大で RecordCount のレコードが移動されます。ソースデータセット内の現在のレコードから最後のレコードまでの数よりも RecordCount の方が大きい場合，ソースデータセットの終わりに達した時点でバッチ移動は終了します。MoveCount を調べると，実際に転送されたレコードの件数を確認できます。


Handling batch move errors
Handling batch move errors1099011

Section topics 	参照

バッチ移動処理で発生する可能性のあるエラーには，データ型変換エラーと整合性違反の 2 種類があります。TBatchMove には，エラー処理の報告および制御をするプロパティが数多くあります。

AbortOnProblem プロパティは，データ型変換エラーが発生したときに処理を中止するかどうかを指定します。 AbortOnProblem が True の場合，エラーが発生するとバッチ移動処理は中止されます。False の場合は継続されます。ProblemTableName に指定したテーブルを調べると，どのレコードが問題を引き起こしたかを確認できます。

AbortOnKeyViol プロパティは，Paradox キー違反が発生したときに処理を中止するかどうかを指定します。

ProblemCount プロパティは，転送先テーブル内での処理でデータが損失したレコードの件数を表します。AbortOnProblem が True の場合，エラーが発生すると処理が中止されるので，この件数は 1 です。

以下のプロパティを使うと，バッチ移動コンポーネントはバッチ移動処理を記述した追加のテーブルを作成できます。

ChangedTableName
これを指定した場合，バッチ処理の結果，転送先テーブルで変更があったすべてのレコードを含むローカル Paradox テーブルが作成されます。

KeyViolTableName
これを指定した場合，Paradox テーブルの操作時にキー違反を引き起こしたソーステーブルのすべてのレコードを含むローカル Paradox テーブルが作成されます。AbortOnKeyViol が True の場合，このテーブルには最大 1 つのエントリが格納されます。

ProblemTableName
これを指定した場合，データ型変換エラーが原因で転送先テーブルに登録できなかったすべてのレコードを含むローカル Paradox テーブルが作成されます。たとえば，転送先テーブルに収まるようにソーステーブルのデータを切り詰める必要があった場合，ソーステーブルのレコードがこのローカルテーブルに含まれます。 AbortOnProblem が True の場合，最初の問題が発生した時点で処理が中止されるので，このテーブルのレコードは最大で 1 つです。

メモ	ProblemTableName を指定していない場合，レコード内のデータは切り詰められて転送先テーブルに入れられます。


See also1099012

TBatchMove


Creating a multi-tiered application
Creating a multi-tiered application1109001

Section topics	参照

この章では，Delphi の新しい分散データセットアーキテクチャを使って多層のクライアント／サーバーデータベースアプリケーションを作成する方法について説明します。多層アプリケーションは最初から作成することも，既存の 2 層クライアント／サーバーデータベースアプリケーションを多層に変換することによって作成することもできます。

多層クライアント／サーバーアプリケーションは，論理ユニットに分割されたデータベースアプリケーションであり，各ユニットは通常別々のマシン上で連係して実行され，ローカルエリアネットワークのほかインターネット上でも互いにデータを共有して通信します。「3 層モデル」と呼ばれるもっとも単純なモデルでは，アプリケーションを以下の 3 つに分割します。

クライアントアプリケーション。ユーザーのマシン上でユーザーインターフェースを提供する

アプリケーションサーバー。クライアントアプリケーションがいくつでも，それらに分散データセットを通じて共通のデータサービスを提供し，クライアントがアクセスできる中央のネットワーク位置に常駐する

リモートデータベースサーバー。リレーショナルデータベース管理システム（RDBMS）を提供する

この 3 層モデルでは，アプリケーションサーバーがクライアントとリモートデータベースサーバー間のデータ交換を管理するので，アプリケーションサーバーを「データブローカー」と呼ぶことがあります。Delphi でデータベースバックエンドを独自に作成することもできますが，通常作成するのはアプリケーションサーバーとそのクライアントだけです。

もっと複雑な多層アプリケーションには，クライアントとリモートデータベースサーバーの間に存在する追加サービスがあります。たとえば，安全なインターネットトランザクションを処理するセキュリティサービスブローカーや，Delphi が直接サポートしていないプラットフォーム上のデータベースとデータを共有するためのブリッジサービスなどがあります。

この章では，主に 3 層データベースアプリケーションの作成について説明します。Delphi には，クライアントとアプリケーションサーバーのデータベース作業の分割とリンクが両方できる新しいコンポーネントがあるからです。3 層アプリケーションの作成と管理の方法を理解すれば，必要に応じて追加サービス層を作成および追加する方法も理解できます。


A structural overview of a multi-tiered application
A structural overview of a multi-tiered application1109002

Section topics	参照

クライアントアプリケーションと対話型の作業をするエンドユーザーにとって，多層データベースアプリケーションの外観と動作は，従来の 2 層アプリケーションと変わりません。ユーザーとの対話は，中間データソースコンポーネントを介してクライアントデータセットコンポーネント（TClientDataSet）に関連付けられた Delphi の標準データベース対応コントロールを通じて行われます。TClientDataSet のプロパティ，イベント，メソッドの使い方についての詳細は，「クライアントデータセットの作成と使い方」を参照してください。

クライアントデータセットはリモートサーバーオブジェクト（TRemoteServer）にリンクされ，リモートサーバーオブジェクトはアプリケーションサーバーへのリンクを確立します。TRemoteServer のプロパティ，イベント，メソッドの使い方についての詳細は，「アプリケーションサーバーへの接続の確立と維持」を参照してください。

クライアントアプリケーションの構造

クライアントアプリケーション上のリモートサーバーオブジェクトは，アプリケーションサーバーへのリンクを確立します。リモートサーバーはアプリケーションサーバー上のデータプロバイダへのインターフェースを受け取ります。Delphi には，プロバイダインターフェースをカプセル化し作成するための TProvider コンポーネントがアプリケーションサーバー用に用意されています。クライアント上のクライアントデータセットはこのデータインターフェースを使ってアプリケーションサーバーに直接データを要求し，更新内容をアプリケーションサーバーに直接送ります。プロバイダオブジェクトは，クライアントデータセットへのインターフェースを提供する ActiveX CoClass でもあり，以下のことを行うデータハンドラでもあります。

クライアントからデータ要求を受け取り，要求されたデータをデータベースサーバーから取り出して，送信のためにデータをパッケージ化し，クライアントデータセットにデータを送る

更新されたデータをクライアントデータセットから受け取り，更新を解決して（データベースへの更新の適用と，適用できない更新の記録），未解決の更新を調停のためにクライアントに返す

TProvider のプロパティ，イベント，メソッドの使い方についての詳細は，「アプリケーションサーバー用のデータプロバイダの作成」を参照してください。

クライアントとアプリケーションサーバーの間でいったんリンクが確立されると，サーバー上のプロバイダとクライアント上のクライアントデータセットが，プロバイダのインターフェースを通じて通信します。プロバイダオブジェクトは，Delphi の標準のデータベースオブジェクトとデータセットオブジェクト（TDatabase，TSession，TSessionList，TQuery，TStoredProc，TTable）を通じてデータベースサーバーとの接続を確立します。

多層クライアント／サーバーアプリケーションでの処理の通常の順序は次のとおりです。

1.	ユーザーがクライアントアプリケーションを起動します。クライアントはアプリケーションサーバーに接続します（設計時または実行時にアプリケーションサーバーを指定できます）。アプリケーションサーバーが実行中でなければ起動されます。クライアントはアプリケーションサーバーからプロバイダインターフェースを受け取ります。

2.	クライアントがアプリケーションサーバーにデータを要求します。クライアントはすべてのデータを一度に要求することもあれば，セッション全体を通じて連続的なデータチャンクを要求することもあります。クライアントデータセットでのデータの取り出しについての詳細は，「多層アプリケーションの作成」を参照してください。

3.	アプリケーションサーバーが，必要であれば最初にデータベース接続を確立してデータベースからデータを取り出し，クライアント用にデータをパッケージ化して，データパケットをクライアントに返します。

4.	クライアントがデータパケットをデコードして，ユーザーにデータを表示します。

5.	ユーザーがレコードを更新し，新しいレコードを挿入します。この変更と追加はクライアントによって変更ログに格納されます。

6.	一般にはユーザーアクションに応じて，最終的にクライアントが更新をアプリケーションサーバーに適用します。更新を適用するために，クライアントは変更ログをパッケージ化してデータパケットとしてサーバーに送ります。

7.	アプリケーションサーバーはパッケージをデコードし，更新と新しいレコードをデータベースサーバーに登録します。レコードをデータベースサーバーに登録できない場合（たとえば，クライアントがレコードを要求してからその更新を適用するまでの間に，別のユーザーまたはアプリケーションがそのレコードを変更したため），アプリケーションサーバーが未登録のレコードを保存します。レコードを登録し，問題のあるレコードをキャッシングするプロセスを「解決」といいます。

8.	解決処理を終了したアプリケーションサーバーが，続けて解決するために未登録のレコードをクライアントに返します。

9.	クライアントが未解決のレコードを調停します。クライアントはさまざまな方法で未解決のレコードを調停できます。通常，クライアントは，レコードの登録を妨げた状況の修正を試みるかまたは変更を破棄します。エラーの状況を修正できる場合，クライアントは再び ApplyUpdates を呼び出して変更をデータベースに書き込みます。

10.	クライアントはサーバーからのデータを更新します。


Advantages of the multi-tiered database model
Advantages of the multi-tiered database model1109003

Section topics	参照

多層データベースモデルでは，データベースアプリケーションを論理的な要素に分割します。クライアントアプリケーションはデータの表示とユーザーとの対話に集中できます。アプリケーションサーバーは，複数のクライアントからのデータ要求を調整および処理し，複数のクライアントからのデータに合わせて更新を行います。アプリケーションサーバーを使うと，すべてのクライアントアプリケーションに対してビジネスルールの標準セットを提供および実施することもでき，ビジネスルールをクライアントごとにエンコードする必要がなくなります。

さらに，多層モデルには，クライアントの軽量化，分散データ処理，データセキュリティの可能性の向上という 3 つの利点があります。

クライアントの実行可能ファイルのサイズは 2 つの理由で小さくなります。1 つは，クライアントが同じマシン上のほかのクライアントとデータアクセス DLL を共有するからであり，もう 1 つは，クライアントがアプリケーションサーバーから受け取った再パッケージ化データに基づいて分散データセットを使うからです。一般に多層アプリケーションの各要素は，互いにほかの要素とは異なるマシン上で実行されるので，アプリケーションは各システムの CPU を効率的に共有して処理をします。多層データベースモデルを使うと，データセキュリティが向上する可能性もあります。なぜなら，各クライアントがリモートデータベースサーバーと直接通信するかわりに，アプリケーションサーバーがすべてのクライアントの仲介者として働き，データベースサーバーへのエントリポイントが減るからです。


Overview of creating a multi-tiered application
Overview of creating a multi-tiered application1109004

Section topics	参照

多層データベースアプリケーションを作成する一般的な手順は次のとおりです。

1.	アプリケーションサーバーを作成し，実行し，登録します。Delphi と一緒に提供されるアプリケーションサーバーコンポーネントは COM に対応しているので，ActiveX アプリケーションまたは OLE アプリケーションを実行する場合と同様にアプリケーションサーバーを登録しなければなりません。アプリケーションの登録についての詳細は，「OLE オートメーションサーバーの作成」を参照してください。

2.	クライアントアプリケーションを作成します。

この順序で作成することが重要です。クライアントを作成する前に，アプリケーションサーバーを作成し，実行しなければなりません。設計時には，クライアントをテストするためにアプリケーションサーバーに接続する必要があります。もちろん，設計時にはアプリケーションサーバーを指定しないでクライアントを作成して，実行時にサーバー名を指定するだけでもかまいませんが，そうすると，設計時にコードを記述して要求したとおりにアプリケーションが動作するかどうかを確認できません。


Creating the application server
Creating the application server1109005

Section topics	参照

アプリケーションサーバーの作成は，ほとんどの Delphi データベースアプリケーションの作成とよく似ています。アプリケーションサーバーでの主な違いは，アプリケーションサーバーには特定の種類のプロバイダインターフェースがなければならない点です。リモートクライアントとの対話用にデュアルインターフェースを確立するには，TProvider コンポーネントを使うことも，TDBDataSet の下位コンポーネント（TTable など）の Provider プロパティを使うこともできます。

アプリケーションサーバーを作成するには，まず新規プロジェクトを開始します。その後の手順は次のとおりです。

1.	プロジェクトに新しいリモートデータモジュールを追加して，適切なテーブル，問い合わせ，ストアドプロシージャの各コンポーネントをリモートデータモジュールに入れ，データベースサーバーにアクセスするようにそれらのコンポーネントを設定します。名前空間が衝突するため，TDatabase コンポーネントはこのリモートデータモジュールに入れられないことに注意してください。TDatabase コンポーネントを使うには，別のデータモジュールに入れ，そのデータモジュールをリモートデータモジュールの uses 節に追加します。

メモ	リモートデータモジュールはデータモジュールとは異なります。OLE オートメーションオブジェクトであり，クライアントアプリケーションとのデュアルインターフェースを確立するため CoClass として機能します。リモートデータモジュールをプロジェクトに追加するには，［ファイル(F)｜新規作成(N)］を選択し，［新規作成］ページから［リモートデータモジュール］フォームを選択します。

2.	アクセスするデータセットごとに，TProvider コンポーネントまたは TDBDataSet の下位コンポーネントをリモートデータモジュールに入れます。

3.	プロバイダコンポーネントを使う場合，プロバイダコンポーネントの DataSet プロパティを，アクセスするデータセットの名前に設定します。プロバイダ用に設定できる追加のプロパティがあります。プロバイダの設定についての詳細は，「アプリケーションサーバー用のデータプロバイダの作成」を参照してください。

4.	必要であればイベント，共有ビジネスルール，共有データ検証，共有セキュリティを実装するアプリケーションサーバーコードを記述します。

5.	アプリケーションサーバーを保存およびコンパイルして，必要であれば実行します。アプリケーションサーバーを使うクライアントアプリケーションを作成および構築するのに，アプリケーションサーバーは必ずしも実行中でなくてもかまいませんが，OLE オートメーションオブジェクトとしてアプリケーションサーバーを登録するにはアプリケーションサーバーを一度実行しなければなりません。また，一般には設計時にクライアントの接続を設定してテストする方がよいでしょう。したがって，クライアントを構築するときにサーバーを実行すると便利です。


Creating the client application
Creating the client application1109006

Section topics	参照

ほとんどの点に関して，多層クライアントアプリケーションの作成は，従来の 2 層クライアントの作成と同じです。主な違いは，多層クライアントが以下の 2 つを使うことです。

アプリケーションサーバーへの仲介を確立するための TRemoteServer コンポーネント

アプリケーションサーバー上のデータプロバイダにリンクするための，1 つまたは複数の TClientDataSet コンポーネント。クライアント上のデータベース対応コントロールは，TTable，TQuery，TStoredProc の各コンポーネントのかわりにデータソースコンポーネントを通じて，これらのクライアントデータセットへ接続される

多層クライアントアプリケーションを作成するには，まず新規プロジェクトを開始します。その後の手順は次のとおりです。

1.	プロジェクトに新しいデータモジュールを追加します。

2.	TRemoteServer コンポーネントをデータモジュールに入れ，ServerName プロパティをアプリケーションサーバーの名前に設定します。ServerName はサーバーのプロセス ID に対応します。リモートサーバーコンポーネントの設定についての詳細は，「アプリケーションサーバーへの接続の確立と維持」を参照してください。

3.	アプリケーションで必要であれば，その他のリモートサーバープロパティを設定します。たとえば，アプリケーションサーバーが別のマシンに常駐しており，DCOM を使う場合，アプリケーションサーバーのマシン名を識別するために ComputerName プロパティを設定しなければなりません。

4.	TClientDataSet コンポーネントをデータモジュールに必要なだけ入れ，各コンポーネントの RemoteServer プロパティを，手順 2 で配置したリモートサーバーコンポーネントの名前に設定します。

5.	各 TClientDataSet コンポーネントの ProviderName プロパティを設定します。設計時にリモートサーバーコンポーネントをアプリケーションサーバーに接続する場合，利用可能なアプリケーションサーバープロバイダを ProviderName プロパティのドロップダウンリストから選択できます。

この時点で，クライアントアプリケーションの作成と Delphi データベースアプリケーションの作成に違いはなくなります。以降の各節では，多層アプリケーションがどのようにレコードを更新するかについて説明し，クライアントとアプリケーションサーバーの各レベルでマスターリンクの更新を処理する方法について説明します。


Establishing and maintaining a connection to an application server
Establishing and maintaining a connection to an application server1109007

Section topics	参照

アプリケーションサーバーへの接続を確立し維持するため，通常はクライアントアプリケーションはデータモジュールで 1 つまたは複数の TRemoteServer コンポーネントを使います。TRemoteServer コンポーネントはコンポーネントパレットの［Data Access］ページにあります。

リモートサーバーコンポーネントは以下のことができます。

アプリケーションサーバー用のコンピュータ名とサーバー名の指定

アプリケーションサーバーへの接続の確立

接続の切断

アプリケーションサーバーへの接続を使うためのクライアントデータセットの登録

実行時のサーバー接続の変更


Specifying an application server's location and name
Specifying an application server's location and name1109008

Section topics	参照

アプリケーションサーバーへの接続を設定するには，リモートサーバーコンポーネントを使います。通常，アプリケーションサーバーはクライアントアプリケーションと別のマシンにあり，したがってリモートサーバーコンポーネントの名前が TRemoteServer になっています。サーバーがクライアントアプリケーションと同じマシンに常駐している場合でも（たとえば，多層アプリケーション全体の構築およびテスト中），リモートサーバーコンポーネントを使ってサーバーの位置と名前を指定できます。

サーバーの位置と名前を指定するには，TRemoteServer の 2 つのプロパティを使います。

ComputerName はサーバーが常駐するマシンを指定する。デフォルトの場合，ComputerName は空白である

ServerName は接続先アプリケーションサーバーの名前を指定する。デフォルトの場合，このプロパティも空白である

これらのプロパティ値の設定方法は，サーバーの位置や，アプリケーションが使う通信転送プロトコルによって異なります。

一般に，ComputerName が空白であれば，Delphi はアプリケーションサーバーがクライアントマシン上に常駐しているとみなし，OLE と DCOM の場合はアプリケーションサーバーにシステムレジストリエントリがあるとみなします。DCOM または OLE を使っている場合にクライアント上にアプリケーションサーバー用のシステムレジストリエントリを用意せず，しかもサーバーがクライアントと異なるマシンに常駐しているならば，ComputerName を指定しなければなりません。

メモ	OLE および DCOM を使っていても，ComputerName を指定してシステムレジストリエントリを変更できます。これは，開発，テスト，デバッグのときに特に便利です。

ServerName は，クライアントアプリケーションを接続するアプリケーションサーバーの名前を指定します。アプリケーションサーバーの GUID を指定することもあります。設計時には，利用可能なアプリケーションサーバーをオブジェクトインスペクタの ServerName プロパティのドロップダウンリストから選択できます。

メモ	指定したホストコンピュータまたはサーバーの名前が見つからないと，例外が生成されます。


Establishing a connection to the server
Establishing a connection to the server1109009

Section topics	参照

設計時と実行時にアプリケーションサーバーへの接続を確立するには，クライアントアプリケーションのリモートサーバーコンポーネントとクライアントデータセットコンポーネントを使います。この手順は次のとおりです。

1.	必要であれば，リモートサーバーコンポーネントの ComputerName プロパティと ServerName プロパティを設定します。

2.	クライアントデータセットの RemoteServer プロパティをリモートサーバーコンポーネントの名前に設定します。

3.	クライアントデータセットの ProviderName プロパティをアプリケーションサーバー上のプロバイダの名前に設定します。設計時にはオブジェクトインスペクタの利用可能なプロバイダのドロップダウンリストから選択できます。

4.	クライアントデータセットを開きます。

この一連の手順の結果，リモートサーバーコンポーネントの GetProvider メソッドが呼び出されます。GetProvider はクライアントデータセットをデータセットのリストに追加し，アプリケーションサーバーへの接続を確立し，IProvider インターフェースを返します。このインターフェースはクライアントに渡されます。クライアントデータセットは，リモートサーバーコンポーネントがアプリケーションサーバーとの接続を維持している限り，このインターフェースを使ってアプリケーションサーバーと直接通信できます。

メモ	IProvider インターフェースは実際にはデュアルインターフェースです。インターフェースと Delphi アプリケーションでのその使い方についての詳細は，「OLE と ActiveX の概要」を参照してください。

BeforeConnect イベントハンドラが存在する場合，GetProvider はリモートサーバーがアプリケーションサーバーへの接続を確立する前にこのイベントハンドラを呼び出します。接続の前に特別な処理を実行したい場合，BeforeConnect ハンドラを記述してそれらの処理を指定しなければなりません。接続を確立した後，指定した特別な処理を実行するために GetProvider は AfterConnect イベントハンドラを呼び出します。


Dropping a server connection
Dropping a server connection1109010

Section topics	参照

リモートサーバーがアプリケーションサーバーへの接続を切断するのは以下の場合です。

クライアントアプリケーションが ServerName プロパティの値を変更した場合

クライアントアプリケーションが Connected プロパティを False に設定した場合

クライアントアプリケーションがリモートサーバーを解放した場合。ユーザーがクライアントアプリケーションを閉じると，リモートサーバーは自動的に解放される

実行時に ServerName または ComputerName を変更すると，クライアントアプリケーションは利用可能なリモートアプリケーションサーバーを切り替えることができます。リモートサーバーは現在の接続を切断し，新規接続を確立します。

BeforeDisconnect イベントハンドラが用意されている場合，リモートサーバーは接続を切断する前に自動的にその BeforeDisconnect イベントハンドラを呼び出します。切断の前に特別な処理を実行したい場合は，BeforeDisconnect ハンドラでその処理を指定しなければなりません。同様に，接続の切断後には AfterDisconnect イベントハンドラが呼び出されます。切断後に特別な処理を実行したい場合は，AfterDisconnect イベントハンドラでその処理を指定しなければなりません。


Changing server connections at runtime
Changing server connections at runtime1109011

Section topics	参照

複数のアプリケーションサーバーを作成する場合は，リモートサーバーコンポーネントの ServerName プロパティを使って実行時にほかのアプリケーションサーバーに切り替えるようにクライアントアプリケーションを作成することができます。このプロパティは，リモートサーバーコンポーネントが接続されるアプリケーションサーバーの名前を指定します。

実行時に ServerName プロパティの値を変更すると，リモートサーバーコンポーネントは現在の接続を切断し，指定されたサーバーへの新規接続を確立します。

メモ	利用可能なアプリケーションサーバー間の切り替えに 1 つのリモートサーバーコンポーネントを使うかわりに，クライアントアプリケーションは，それぞれ異なるアプリケーションサーバーに接続できる複数のリモートサーバーコンポーネントを使うこともできます。


Accessing data with client datasets
Accessing data with client datasets1109012

Section topics	参照

多層データベースアプリケーションでデータにアクセスするには，1 つまたは複数の TClientDataSet コンポーネントがあるクライアントアプリケーションを使います。クライアントデータセットについての詳細は，「クライアントデータセットの作成と使い方」を参照してください。

クライアントデータセットコンポーネントを使うと，データの管理，表示，編集ができます。クライアントアプリケーションのクライアントデータセットは，通常はアプリケーションサーバーからデータを取得します。ブリーフケースモデル（ユーザーがデータのコピーをダウンロードし，オフラインで作業し，後で変更内容をアプリケーションサーバーにアップロードできます）もサポートする多層データベースアプリケーションを作成すると，クライアントデータセットはフラットファイルでのデータの読み書きもできます。ブリーフケースモデルをサポートするクライアントアプリケーションの作成についての詳細は，「ブリーフケースモデルのサポート」を参照してください。

クライアントアプリケーションの各データモジュールには，クライアントデータセットコンポーネントを必要なだけ配置します。データソースコンポーネントを通じてデータベース対応コントロールをクライアントデータセットにリンクする方法は，TDataSet の下位コンポーネントの場合と同じです。しかし，クライアントデータセットをデータベースサーバーにリンクする方法は，ほかのデータセットのリンク方法とは異なります。クライアントデータセットは基になるデータベーステーブルには直接リンクされません。そのかわりに，まず「データブローカー」つまりアプリケーションサーバーにリンクされます。このアプリケーションサーバーがデータベースサーバーへのリンクを維持します。アプリケーションサーバーへのクライアントデータセットのリンクについての詳細は，「クライアントデータセットの作成と使い方」を参照してください。


Handling constraints
Handling constraints1109013

Section topics	参照

デフォルトでは，データベースサーバーの制約とデフォルト式が SQL エクスプローラによって自動的にインポートされ，属性セットを通じて複製されます。その結果，サーバーの制約とデフォルト式はアプリケーションサーバーを通じてクライアントデータセットに渡されます。クライアントデータセットでは，サーバー制約とデフォルト式をユーザーのデータ編集時に適用できます。クライアントデーセットでサーバー制約を使うと，アプリケーション間の一貫性を保つことができます。たとえば，制約が有効な場合，ユーザーがクライアントアプリケーションのデータに行った編集が制約に違反するようなときは，編集内容はクライアント側には適用されるが，アプリケーションサーバーには渡されずに結局はデータベースサーバーによって拒否されます。重要なのは，更新中にエラー条件が生じる可能性が低くなることです。

サーバーの制約と式をインポートすると開発者がプラットフォームやアプリケーション間のデータの整合性を維持できるため非常に便利ですが，アプリケーションは一時的に制約を解除しなければならないことがあります。たとえば，サーバーの制約が項目内の現在の最大値に基づいている場合，クライアントデータセットが複数のレコードパケットを取り出すと，クライアント側の項目内の現在の最大値がデータベースサーバーの最大値と異なり，制約の適用方法が異なってくることがあります。また，制約が有効な場合にクライアントアプリケーションがレコードにフィルタを適用すると，フィルタが制約条件を妨害してしまうことがあります。どちらの場合も，データを要求する前に，アプリケーションが制約を解除できます。

制約を一時的に解除するには，クライアントデータセットの DisableConstraints メソッドを呼び出します。DisableConstraints が呼び出されるたびに，参照カウントが増えていきます。参照カウントがゼロより大きければ，クライアントデートセットに対する制約は適用されません。

クライアントデータセットに対する制約を再度適用するには，データセットの EnableConstraints メソッドを呼び出します。EnableConstraints を呼び出すたびに参照カウントが減っていきます。参照カウントがゼロになると，制約が再度適用されます。

参考	DisableConstraints と EnableConstraints は必ず対にして呼び出し，必要に応じて制約を適用できるようにします。

データセットでの制約とデフォルト式の処理については，「項目コンポーネントの操作」と「データセットについて」を参照してください。


Updating records
Updating records1109014

Section topics	参照

クライアントアプリケーションがアプリケーションサーバーに接続されると，クライアントデータセットはアプリケーションサーバーによって渡されたデータのローカルコピーを処理します。ユーザーはこれらのコピーをクライアントアプリケーションのデータベース対応コントロールで表示し，編集できます。クライアントデータセットに対してサーバーの制約が適用されている場合は，ユーザーが可能な編集もそれに応じて制約されます。ユーザーが行った変更はクライアントデータセットが内的に保持している変更ログに一時的に格納されます。変更ログの内容は Delta プロパティにデータパケットとして格納されます。Delta 内の変更を確定するには，クライアントデータセットが ApplyUpdates を呼び出して変更内容をデータベースに適用しなければなりません。

更新は実際には次の 4 段階のプロセスでデータベースに書き込まれます。

1.	クライアントアプリケーションが，クライアントデータセットオブジェクトに属している ApplyUpdates メソッドを呼び出します。この ApplyUpdates メソッドは，クライアントデータセットの Delta プロパティの内容を，クライアントデータセットに現在関連付けられている IProvider インターフェースを通じてアプリケーションサーバーに渡します。Delta はクライアントデータセットで更新，挿入，削除されたレコードが入っているデータパケットです。

2.	アプリケーションサーバーの TProvider オブジェクトが自身の ApplyUpdates メソッドを呼び出してデータベースを更新します。更新とは，クライアントから受け取ったキャッシュ内の各レコードを，データベース内の対応するレコードを使って解決する試みです。解決はレコード単位のプロセスです。

プロバイダが，更新または挿入されたレコードをデータベースに書き込めるかまたは削除されたレコードをデータベースから削除できれば，レコードレベルの解決は成功です。

変更されたレコードをプロバイダがデータベースに書き込めなければ，レコードレベルの解決は失敗です。通常，解決が失敗するのは，このクライアントアプリケーションがデータベースレコードを取り出してから，このクライアントが更新の適用を要求するまでの間に，別のアプリケーションがそのデータベースレコードを変更した場合です。この場合，調停のためにクライアントアプリケーションへ返せるように，プロバイダがクライアント版のレコードを保存します。

3.	アプリケーションサーバーの TProvider オブジェクトがレコードの解決をすべて完了して，未解決のすべてのレコードをエラーの調停用にクライアントに返します。

4.	クライアントアプリケーションの調停エラーハンドラがレコード単位でエラー条件の修正を試みます。

アプリケーションサーバーはレコード単位で実際の更新処理を実行します。アプリケーションサーバーは各レコードをデータベースに適用します。エラーが発生した場合，たとえばレコードの変更のためにサーバー制約が無効になるためデータベースサーバーがその変更を拒否する場合などは，アプリケーションサーバーが独自にエラーの解決を試みることができます。エラー条件を解決できなかった場合，アプリケーションサーバーはエラーレコードのコピーを一時的に格納します。レコードの処理が完了すると，アプリケーションサーバーは Result データパケットをクライアントデータセットに返します。この Result データパケットには未更新のレコードがすべて入っています。エラーメッセージやエラーコードなどのエラー情報も入っています。

クライアントデータセットはアプリケーションサーバーから返されたデータパケットを使って，OnReconcileError イベントハンドラ内でエラーを調停します。OnReconcileError イベントハンドラはデータパケットのレコードごとに 1 回ずつ呼び出されます。OnReconcileError ハンドラ内でのエラー調停についての詳細は，「更新エラーの調停」を参照してください。

Applying updates1109015

クライアントデータセットのローカルデータコピーの変更は，クライアントアプリケーションがそのデータセットの ApplyUpdates 関数を呼び出すまでアプリケーションサーバーには送られません。ApplyUpdates は 1 つのパラメータ MaxErrors を取ります。MaxErrors は，アプリケーションサーバーが更新プロセスを停止するまでの最大許容エラー数を示します。ApplyUpdates は実際に検出したエラーの数を返します。この値は必ず MaxErrors に 1 を加えた値以下でなければなりません。この値は，データベースに書き込めなかったレコードの数を示すために設定されます。アプリケーションサーバーは書き込めなかったレコードもそのデータセットのクライアントデータセットに返します。

クライアントデータセットは，エラーを生じたレコードを調停しなければなりません。ApplyUpdates は実際にはクライアントデータセットの Reconcile メソッドを呼び出して更新をアプリケーションサーバーに送ります。Reconcile は，クライアントデータセットに OnReconcileError イベントハンドラが存在していれば，サーバー側でエラーを生じたレコードごとに 1 回ずつこのイベントハンドラを起動します。エラーを生じたレコードの調停方法についての詳細は，「更新エラーの調停」を参照してください。


Reconciling update errors
Reconciling update errors1109016

Section topics	参照

ApplyUpdates を実行すると，クライアントデータセットとアプリケーションサーバーの TProvider コンポーネントの間に確立された IProvider インターフェースを通じて，クライアントアプリケーションの変更ログ（Delta）のレコードがアプリケーションサーバーに渡されます。プロバイダはエラーレコードとエラー情報を結果データパケットに入れてクライアントデータセットに返します。ApplyUpdates は次にクライアントデータセットの Reconcile メソッドを呼び出してエラーを処理します。アプリケーションサーバーがゼロより大きいエラー数を返すと，Reconcile が結果データパケット内のレコードごとにそのクライアントデータセットの OnReconcileError イベントハンドラを呼び出します。

OnReconcileError イベントハンドラは必ず記述しなければなりません。アプリケーションサーバーが返すレコードを破棄するだけの場合にも必要です。

注意	OnReconcileError イベントハンドラの中では，現在のレコードを変更するクライアントデータセットメソッド（Next や Prior など）は呼び出さないでください。このようなメソッドを呼び出すと，イベントハンドラが無限ループに入ります。

OnReconcileError イベントハンドラの概略コードは次のとおりです。

procedure TForm1.ClientDataSetReconcileError(DataSet: TClientDataSet; E:EReconcileError;

  UpdateKind: TUpdateKind; var Action: TReconcileAction);

begin

  { ここで調停を行う ... }

end;

DataSet は更新の適用先のクライアントデータセットを参照します。以降の各節では，調停エラーハンドラに渡される各パラメータについてと，それらのパラメータの使い方について説明します。

Indicating the type of update that generated an error1109017

UpdateKind は TUpdateKind 型のパラメータで，エラーを生成した更新の種類を示します。実行中の更新の種類に基づいてエラーハンドラで特別な処理を実行するのでなければ，コードでこのパラメータを使うことはないでしょう。

表に UpdateKind で可能な値を示します。

値	意味
ukModify	既存のレコードの編集でエラーになった
ukInsert	新規レコードの挿入でエラーになった
ukDelete	既存のレコードの削除でエラーになった
Specifying the action to take1109018

Action は，OnReconcileError ハンドラの終了時に実行する処理を示します。ハンドラに制御が渡ると，Action は必ずサーバー側の解決プロセスで実行される処理に設定されます。次の表に，Action で可能な値とその意味を示します。

値	意味
raSkip	エラー条件を生成したレコードの更新をスキップし，未適用の変更を変更ログに残す
raAbort	調停操作を中止する
raMerge	更新レコードをサーバーのレコードとマージする
raCorrect	更新レコードをデータベースに再度適用する
raCancel	変更レコードを変更ログから削除する
raRefresh	現在のレコード値を更新し，変更レコードを変更ログから削除する
メモ	OnReconcileError ハンドラのコードでは，現在のレコードの項目ごとにプロパティ OldValue，NewValue，CurValue を調べて適用することはできますが，別のレコードを現在のレコードにするメソッドは呼び出さないでください。

エラーハンドラの呼び出しの原因となったエラー条件をエラーハンドラで修正できる場合は，Action を終了時にとるべき適切な処理に設定します。エラー条件を修正できた場合は，Action を raMerge または raCorrect に設定してそのレコードの更新を再度適用します。

raSkip に設定すると，エラーを引き起こした行の更新はスキップされ，そのレコードの更新はほかのすべての更新が完了した後でキャッシュに残ります。

raAbort は更新操作全体を終了します。

Working with error message text1109019

E パラメータは EReconcileError 型です。この例外の型からは，ユーザーに表示できるエラーメッセージをエラーハンドラで抽出できます。たとえば次のコードは，ダイアログボックスのキャプションにエラーメッセージを表示するのに使えます。

ErrorLabel.Caption := E.Message;

このパラメータは，更新エラーの実際の原因を調べる場合にも役立ちます。EReconcileError から特定のエラーコードを抽出し，そのコードに基づいて適切な処理を実行できます。たとえば次のコードは，更新エラーがキー違反に関係するかどうかを調べ，関係する場合は Action パラメータを raSkip に設定します。

if E is EReconcileError then

  with EReconcileError(E) do

  begin

    if ErrorCode = DBIERR_KEYVIOL then

      Action := raSkip  { キー違反の場合，このレコードをスキップする }

    else

      Action := raAbort { 原因不明の場合，更新を中止する }

  end;


Creating a data provider for the application server
Creating a data provider for the application server1109020

Section topics	参照

通常は，アプリケーションサーバー上のリモートデータモジュールごとに 1 つまたは複数の TProvider コンポーネントを入れます。プロバイダコンポーネントは，アプリケーションサーバーのリモートデータモジュールの TStoredProc，TQuery，TTable のいずれかのデータセットコンポーネントと，クライアントアプリケーションのクライアントデータセットの間に IProvider インターフェースを確立します。プロバイダはこのデータセットとクライアントアプリケーションのクライアントデータセットとの仲介の役目を果たします。

メモ	リモートデータモジュールに入れた TProvider コンポーネントを使ってクライアントデータセットに対する IProvider インターフェースを確立するかわりに，TStoredProc，TQuery，TTable の Provider プロパティを使ってインターフェースを確立し，TProvider を明示的に使うのを完全に避けることもできます。データセットコンポーネントの Provider プロパティを直接使うと，Delphi が IProvider インターフェースを自動的に作成して管理するので，開発者は制御できません。TProvider を使えば，アプリケーションでプロバイダインターフェースをより直接的に制御できます。


Linking to a source dataset
Linking to a source dataset1109021

Section topics	参照

プロバイダコンポーネントをアプリケーションサーバー上の特定の BDE 対応データセットコンポーネントに関連付けるには，プロバイダの DataSet プロパティを，使うデータセットの名前に設定します。設計時には，オブジェクトインスペクタの DataSet プロパティのドロップダウンリストから使用可能なデータセットを選択できます。

ここでクライアントアプリケーションは，リモートサーバーコンポーネントを使います。

1.	アプリケーションサーバーへの接続を確立しすます。

2.	クライアントデータセットの ProviderName プロパティをプロバイダコンポーネントに設定してプロバイダのデータセットにリンクしします。

3.	データを取り出すことができます。

クライアントとプロバイダは IProvider インターフェースを通じて直接通信できます。


Establishing a connection with a client application
Establishing a connection with a client application1109022

Section topics	参照

アプリケーションサーバーを設定して実行しても，クライアントアプリケーションとの接続は確立されません。そのかわりに，クライアントアプリケーションがリモートサーバーコンポーネントを使ってアプリケーションサーバーとの接続を確立し，接続が確立されたらプロバイダを選択します。ほとんどの場合，アプリケーションサーバーの TProvider コンポーネントのうちの 1 つがプロバイダとして選択されます。

プロバイダが選択されると，そのプロバイダはクライアントとの通信用に COM インターフェースを確立します。COM インターフェースを IProvider といいます。IProvider は IDispatch インターフェースから派生し，アプリケーションサーバーと特定のクライアントデータセットの間のデュアルインターフェースとして実装されます。クライアント接続ごとにアプリケーションサーバーとの独自のインターフェースが確立されます。COM，デュアルインターフェース，IDispatch についての詳細は，「OLE と ActiveX の概要」を参照してください。

接続が確立した後は，アプリケーションサーバーとクライアントデータセット間のインターフェースは自動式なので，開発者やユーザーが意識することはありません。接続はクライアントアプリケーションが維持します。


Handling client requests for data
Handling client requests for data1109023

Section topics	参照

ほとんどの多層アプリケーションでは，クライアントからのデータ要求が自動的に処理されます。クライアントデータセットは，FetchOnDemand プロパティの設定に基づいていつデータを受け取るかを指定します。また，一度に取り出すデータの量を PacketRecords プロパティで指定します。これらのプロパティのデフォルト設定を使うと，クライアントデータセットを開いたときに，アプリケーションサーバーがそのデータセットに使用可能なすべてのデータをすぐに送るようになります。

クライアントアプリケーションが複数のデータパケットでデータを受け取るように PacketRecords を設定しても，FetchOnDemand が True（デフォルト）のままであれば，クライアントアプリケーションは必要に応じてアプリケーションサーバーのプロバイダに自動的にデータを要求します。プロバイダはまだ送るデータがあれば，そのデータを送ることでこれらの要求に必ず応答します。

メモ	IProvider インターフェースの DataRequest メソッドを呼び出すアプリケーションサーバーを作成すると，データ要求をカスタマイズできます。


Handling update requests on the application server
Handling update requests on the application server1109024

Section topics	参照

プロバイダは，クライアントアプリケーションから受け取った Delta データパケットに基づいてデータベースレコードに更新を適用します。プロバイダは更新要求を受け取ると，自身の ApplyUpdates メソッドを呼び出してレコードをデータベースに書き込みます。

アプリケーションサーバーはレコード単位で実際の更新処理を実行します。アプリケーションサーバーは各レコードをデータベースに適用します。エラーが発生した場合，たとえばレコードの変更のためにサーバー制約が無効になるためデータベースサーバーがその変更を拒否する場合などは，アプリケーションサーバーはエラーを解決するために OnUpdateError イベントハンドラを呼び出します。エラー条件を解決できなかった場合，アプリケーションサーバーはエラーレコードのコピーを一時的に格納します。レコードの処理が完了すると，アプリケーションサーバーは検出したエラーの数をクライアントデータセットに返し，未解決のレコードを結果データパケットにコピーします。このデータパケットは調停のためクライアントに返されます。

メモ	通常，更新エラーはアプリケーションサーバーでは処理せず，クライアントアプリケーションに返して解決しなければなりません。エラーによっては解決のためユーザーとの対話が必要になり，ユーザーとの対話はクライアントアプリケーションで行われるというのがその理由の 1 つです。ただし，次の節では，開発者がアプリケーションサーバーレベルでエラーを処理しなければならないときのために，OnUpdateError ハンドラについて説明します。

Resolving update errors on the provider1109025

プロバイダでは，ApplyUpdates メソッドが OnUpdateError イベントハンドラを呼び出してエラー条件を解決しようとします。一般的には，ユーザーと対話してエラー条件を修正できる場合は，クライアントでエラーを処理する方が適切です。OnUpdateError ハンドラはほとんどの場合，エラーが生じているレコードやエラー情報をクライアントアプリケーションに返すだけです。

procedure TForm1.Provider1UpdateError(DataSet: TClientDataSet, E: EUpdateError;

  UpdateKind: TUpdateKind; var Response: TResolverResponse);

begin

  { ここでエラーを解決する ... }

end;

以降の各節では，更新エラーハンドラに渡される各パラメータについてと，それらのパラメータの使い方について説明します。

Referencing the dataset to which to apply updates1109026

DataSet は更新を適用するために一時的に使うクライアントデータセットを参照します。各項目の NewValue プロパティと OldValue プロパティを使うと，このデータセットに関連付けられたレコードを表示し，処理できます。

Indicating the type of update that generated an error1109027

UpdateKind は TUpdateKind 型のパラメータで，エラーを生成した更新の種類を示します。実行中の更新の種類に基づいてエラーハンドラで特別な処理を実行するのでなければ，コードでこのパラメータを使うことはないでしょう。

表に，UpdateKind で可能な値を示します。

値	意味
ukModify	既存のレコードの更新でエラーになった
ukInsert	新規レコードの挿入でエラーになった
ukDelete	既存のレコードの削除でエラーになった
Specifying the action to take1109028

Response は TResolverResponse 型のパラメータです。エラーハンドラを初めて呼び出した場合，このパラメータの値は必ず rrSkip に設定されます。エラーを修正しない場合は，この値を変更する必要はありません。表に Response に設定できる値を示します。

値	意味
rrSkip	レコードの更新をスキップし，それを記録し，エラー条件を結果データパケットに入れてクライアントに返す
rrAbort	更新操作を中止し，レコードとエラー条件を結果データパケットに入れてクライアントに返す
rrMerge	変更レコードをデータベースのレコードとマージする
rrApply	修正した更新内容をデータベースに適用する
rrIgnore	レコードを無視し，そのレコードもエラー情報も結果データパケットに格納しない。このオプションを使うと，クライアントにエラーの発生を知らせずに，エラーを引き起こした更新が取り消されるので注意が必要である。この結果，クライアントは更新が成功した場合と同じように変更ログからその更新を自動的に削除することになる
エラーハンドラの呼び出しの原因となったエラー条件をエラーハンドラで修正できる場合は，Response を終了時にとるべき適切な処理に設定します。エラー条件を修正できた場合は，Response を rrMerge または rrApply に設定してそのレコードの更新を再度適用します。

rrSkip に設定すると，エラーを引き起こした行の更新はスキップされますが，そのレコードとエラー情報が結果データパケットに追加されます。プロバイダがデータベースの更新を完了すると，このデータパケットはクライアントデータセットに送り返されます。

rrAbort は更新操作全体を終了します。データベースに更新は適用されず，すべてのレコードが未変更のままクライアントに返されます。

Working with error message text1109029

E パラメータは通常 EUpdateError 型です。この例外の型からは，ユーザーに表示できるエラーメッセージをエラーハンドラで抽出できます。たとえば次のコードは，ダイアログボックスのキャプションにエラーメッセージを表示するのに使えます。

ErrorLabel.Caption := E.Message;

このパラメータは，更新エラーの実際の原因を調べる場合にも役立ちます。EUpdateError から特定のエラーコードを抽出し，そのコードに基づいて適切な処理を実行できます。たとえば次のコードは，更新エラーがキー違反に関係するかどうかを調べ，関係する場合は Response パラメータを rrSkip に設定します。

if E is EUpdateError then

  with EUpdateError(E) do

  begin

    if ErrorCode = DBIERR_KEYVIOL then

      Response := rrSkip  { キー違反の場合，このレコードをスキップする }

    else

      Response := rrAbort { 原因不明の場合，更新を中止する }

  end;


Handling server constraints
Handling server constraints1109030

Section topics	参照

ほとんどのリレーショナルデータベース管理システムでは，データの整合性を実現するためにテーブルに制約を設けています。制約は，テーブルと列のデータ値についての規則，または各種テーブル内の列相互のデータ関係についての規則です。たとえば，SQL-92 準拠のほとんどのリレーショナルデータベースは，以下の制約をサポートしています。

NOT NULL。列に与える値がヌルにならないようにする

NOT NULL UNIQUE。列値がヌルにならないようにし，別のレコードでその列にすでにあるほかのどの値とも重複しないようにする

CHECK。列に与える値が一定の範囲内になるか，一定数の可能な値のどれかになるようにする

CONSTRAINT。テーブル全体を検査する制約で，複数の列に適用される

PRIMARY KEY。インデックス付けのために 1 つまたは複数の列をテーブルの一次キーと指定する

FOREIGN KEY。あるテーブル内の 1 つまたは複数の列がほかのテーブルを参照することを指定する

メモ	制約は以上に限られるわけではありません。データベースサーバーはこれらの制約の一部またはすべてを部分的にでも全体的にでもサポートできます。これらのほかにも制約をサポートすることがあります。サポートされている制約についての詳細は，各サーバーのマニュアルを参照してください。

データベースサーバーの制約は，従来のデスクトップデータベースアプリケーションでこれまで管理してきたさまざまなデータ検査を明らかに複製します。多層データベースアプリケーションでは，アプリケーションサーバーやクライアントアプリケーションのコードでサーバーの制約を複製しなくても，その制約を利用できます。

プロバイダの Constraints プロパティを使えば，サーバーの制約を複製して，クライアントアプリケーションとの間で受け渡すデータに適用できます。Constraints が True（デフォルト）の場合，サーバーの制約はクライアントに複製され，クライアントによるデータ更新の試みに影響を与えます。

メモ	クライアントアプリケーションに送るデータにサーバーの制約を適用したくない場合があります。たとえば，パケットでデータを受け取り，さらにレコードを取得する前にレコードのローカル更新が可能なクライアントアプリケーションの場合，更新対象の一連のデータが一時的に不完全になるため，適用される可能性のある一部のサーバー制約を解除しなければならないことがあります。アプリケーションサーバーからクライアントデータセットへの制約の複製を防ぐには，Constraints を False に設定します。クライアントデータセットも，アプリケーションサーバーから制約を受け取った場合でも，その制約を解除したり適用したりできるので注意してください。クライアントデータセットでの制約の処理についての詳細は，「クライアントデータセットの作成と使い方.」を参照してください。


Supporting the briefcase model
Supporting the briefcase model1109031

Section topics	参照

この章では，クライアントアプリケーションを作成し，アプリケーションサーバーと一緒に使う方法について主に説明してきました。このモデルでは，ユーザーは 1 つのマシンでクライアントアプリケーションを起動し，ネットワークを通じてリモートマシン上のアプリケーションサーバーに接続します。クライアントはアプリケーションサーバーにデータを要求し，更新をアプリケーションサーバーに送ります。アプリケーションサーバーは受け取った更新を，組織内のほかのクライアントと共有しているデータベースに適用します。

ただし，オンサイトの企業データベースには貴重な顧客連絡先データが入っており，販売担当者が出先でそのデータを使ったり更新したりできるとします。この場合，販売担当者が企業データベースからデータの一部またはすべてをダウンロードし，国内のどこででもラップトップコンピュータでそれを操作し，さらには既存または新規の顧客サイトでレコードを更新できると便利です。販売担当者がオンサイトに戻ったら，データ変更を企業データベースにアップロードし，社内の全員がそれを使えるようにすることができます。データをオフラインで操作し，後でデータに更新をオンラインで適用できる機能を「ブリーフケース」モデルといいます。

自分のサイトでブリーフケースモデルを使える場合，フラットファイルを読み書きするクライアントデータセットコンポーネントの機能を利用してクライアントアプリケーションを作成し，アプリケーションサーバーと一緒にオンラインで使うことも，オフラインで一時的な単一層アプリケーションとして使うこともできます。

アプリケーションサーバーと一緒に使うことも，スタンドアロンの単一層アプリケーションとして使うこともできるクライアントアプリケーションを作成するには，以下の操作を可能にするコードをクライアントアプリケーションに追加しなければなりません。

ユーザーがアプリケーションサーバーからデータを読み出し，ローカルファイルに保存する

ユーザーがローカルファイルからデータをロードし，アプリケーションサーバーに適用する

起動時に接続するアプリケーションサーバーの有無を調べ，状況に応じて適切な IProvider インターフェースを確立する。たとえば，クライアントがアプリケーションサーバーに接続できる場合，アプリケーションサーバーから IProvider インターフェースを派生させる。そうでない場合は，クライアントアプリケーションが自動的に IProvider を作成しなければならない（ただし，Delphi は必要であればすぐに IProvider を作成できる）

クライアントデータセットのプロバイダインターフェースと，クライアントデータセットでのファイルへのデータの読み書きについての詳細は，「クライアントデータセットの作成と使い方」を参照してください。


Modifying a two-tiered application to use the multi-tiered model
Modifying a two-tiered application to use the multi-tiered model1109032

Section topics	参照

2 層の Delphi クライアント／サーバーアプリケーションの場合，アプリケーションはクライアントであり，データベースサーバーと直接通信します。この場合でも，データベース接続とユーザーインターフェースという 2 つの要素がアプリケーションにあると考えることができます。2 層クライアント／サーバーアプリケーションを多層アプリケーションにするには，以下のことが必要です。

既存のアプリケーションを，データベース接続を処理するアプリケーションサーバーと，ユーザーインターフェースを持つクライアントアプリケーションに分割する

クライアントとアプリケーションサーバーの間のインターフェースを追加する

作業の進め方はいくつもありますが，次の手順に従うと変換作業が最小限ですみます。

1.	アプリケーションサーバーの新規プロジェクトを作成して，以前の 2 層アプリケーションのデータベース接続に関連する部分を複製します。アプリケーションサーバーとクライアントの間でデータを仲介するために，TProvider コンポーネントを使えるように複製部分を修正します。TProvider コンポーネントの使い方についての詳細は，「アプリケーションサーバー用のデータプロバイダの作成」を参照してください。

2.	既存の 2 層のプロジェクトをコピーして，直接的なデータベース接続を削除し，TRemoteServer コンポーネントを追加して，元のプロジェクト内の TTable，TQuery，TStoredProc の各コンポーネントを TClientDataSet コンポーネントで置き換えます。TTable，TQuery，TStoredProc の各コンポーネントをアプリケーションサーバーのデータモジュールに移動し，手順 1 でアプリケーションサーバー用に作成した TProvider インターフェースを使うようにこれらのコンポーネントを設定します。BDE 対応データセットをプロバイダコンポーネントにリンクする方法についての詳細は，「ソースデータセットへのリンク」を参照してください。リモートサーバーコンポーネントの作成と使い方についての詳細は，「アプリケーションサーバーへの接続の確立と維持」を参照してください。クライアントデータセットコンポーネントの使い方については「クライアントデータセットの作成と使い方」を参照してください。


See also1109033

TProvider

TDatabase

TRemoteServer

TDataSet

TClientDataSet

TDBDataSet

TTable

TQuery

TSession

TSessionList

TStoredProc

データアクセスコンポーネント


Overview of component creation
Overview of component creation1113001

Section topics 	参照

この章では，Delphi アプリケーション用コンポーネントの設計と開発プロセスについての概要を示します。このマニュアルは，Delphi とその標準コンポーネントについてのある程度の知識を前提として記述されています。この章では以下のことについて説明します。

ビジュアルコンポーネントライブラリ

コンポーネントとオブジェクト

コンポーネントの作成

コンポーネントのさまざまな側面

新しいコンポーネントの作成

インストールされていないコンポーネントのテスト


The Visual Component Library
The Visual Component Library1113002

Section topics 	参照

Delphi のコンポーネントは，ビジュアルコンポーネントライブラリ（VCL）というクラス階層を構成しています。図に，VCL を構成するクラスの関係を示します。

VCL では TComponent クラスがすべてのコンポーネントに共通の上位クラスになっています。TComponent は，コンポーネントが Delphi で動作するために最小限必要なプロパティとイベントを定義します。そして，このライブラリのさまざまな下位クラスが，それ以外のより特化した能力を実現します。

コンポーネントを作成する場合は，このクラス階層内の既存のクラス型の 1 つから新しいクラスを派生させます。


Components and classes
Components and classes1113003

Section topics 	参照

コンポーネントはクラスであり，コンポーネント開発者はアプリケーション開発者とは異なるレベルでオブジェクトを使用します。新しいコンポーネントを作成するには，新しいクラスを派生させる必要があります。

要約すると，コンポーネントの作成とアプリケーションでのコンポーネントの使用との間には，次の 2 つの主要な相違点があります。

コンポーネント開発者は，アプリケーションプログラマがアクセスできないクラスの各部分にもアクセスする

コンポーネント開発者は，コンポーネントに（プロパティなどの）新しい部分を追加する

このため，コンポーネント開発者はコンポーネントについてより詳しく理解しておく必要があります。また，開発したコンポーネントをアプリケーション開発者がどのように使用するのかということについても考慮しなければなりません。


How do you create components?
How do you create components?1113004

Section topics 	参照

開発者が設計時に扱うプログラム要素のほとんどはコンポーネントです。コンポーネントを作成するには，既存のクラスから新しいクラスを派生させます。コンポーネントは任意のコンポーネントから派生できますが，一般に以下のような方法で作成します。

既存のコントロールの変更

独自のコントロールの作成

グラフィックコントロールの作成

Windows コントロールのサブクラスの作成

非ビジュアルコンポーネントの作成

表に，コンポーネントの各作成方法で，派生元として使用するクラスを要約します。

種類	派生元となるオブジェクト型
既存のコンポーネントの変更	TButton や TListBox などの既存のコンポーネントか，TCustomListBox などの抽象コンポーネント型
独自のコントロールの作成	TWinControl
グラフィックコントロールの作成	TGraphicControl
Windows コントロールのサブクラスの作成	Windows コントロール
非ビジュアルコンポーネントの作成	TComponent
また，コンポーネントではないクラスを派生させることもできますが，そうしたクラスはフォームの中では操作できません。Delphi には，TIniFile や TFont などのクラスも多数あります。


Modifying existing controls
Modifying existing controls1113005

Section topics 	参照

コンポーネントを作成する最も簡単な方法は，既存のコンポーネントをカスタマイズする方法です。Delphi が提供するどのコンポーネントからでも，新しいコンポーネントを派生させることができます。

リストボックスやグリッドのようなコントロールには，共通の基本的な機能を持ついくつかのバリエーションがあります。VCL にはこれらに対応した抽象クラスがあります。抽象クラスは，新しくカスタマイズしたコンポーネントを派生させる元として使用できます。なお，Delphi の抽象クラスの名前は，TCustomGrid などのように「custom」という文字列を含みます。

たとえば，標準の TListBox クラスのプロパティからいくつかを除いて，特別なリストボックスを作成するとします。上位クラスからプロパティを除去することはできないので，TListBox より上位の階層のクラスからそのコンポーネントを派生します。この場合，抽象 TWinControl クラスまで戻ってしまうと，リストボックスの機能を再びすべて作成しなければなりません。そのため，VCL には，TCustomListBox が提供されています。この TCustomListBox には，リストボックスのプロパティがあります。ただし，そのすべてがパブリッシュに設定されているわけではありません。TCustomListBox などのような抽象クラスからコンポーネントを派生させる場合には，開発するコンポーネントで使用するプロパティだけをパブリッシュに設定し，そのほかのプロパティはプロテクト設定のまま残します。


Creating windowed controls
Creating windowed controls1113006

Section topics 	参照

ウィンドウコントロールは実行時に表示され，ユーザーが対話できるオブジェクトです。各ウィンドウコントロールにはウィンドウハンドルがあり，ウィンドウハンドルには Handle プロパティを通じてアクセスします。ウィンドウハンドルにより Windows はそのコントロールを識別して操作できます。ウィンドウハンドルがあるためコントロールは入力フォーカスを受け取ることができます。ウィンドウハンドルは Windows API 関数に渡すことができます。

すべてのウィンドウコントロールは TWinControl クラスから派生します。ウィンドウコントロールにはプッシュボタン，リストボックス，編集ボックスなど，ほとんどの標準 Windows コントロールが含まれます。TWinControl からオリジナルのコントロール（既存のコントロールに関連していないコントロール）を直接派生させることができますが，このような派生のために Delphi では TCustomControl コンポーネントが用意されています。TCustomControl は，複雑なビジュアルイメージを描画しやすくする専用のウィンドウコントロールです。


Creating graphic controls
Creating graphic controls1113007

Section topics 	参照

コントロールが入力フォーカスを受け取る必要がない場合は，そのコントロールをグラフィックコントロールにできます。グラフィックコントロールはウィンドウコントロールに似ていますが，ウィンドウハンドルを持たないので，システムリソースを節約できます。TLabel のような入力フォーカスを受け取らないコンポーネントがグラフィックコントロールです。

Delphi では，グラフィックコントロールの作成のために TGraphicControl コンポーネントを用意しています。TGraphicControl は，TControl から派生したクラスです。作成するコントロールを TControl から直接派生させることもできますが，TGraphicControl から派生させる方がはるかに簡単です。なぜなら，TGraphicControl ではペイント用のキャンバスが用意され，また WM_PAINT メッセージも処理されるからです。開発者に必要な作業は，Paint メソッドをオーバーライドすることだけです。


Subclassing Windows controls
Subclassing Windows controls1113008

Section topics 	参照

従来の Windows プログラミングでカスタムコントロールを作成するには，新しいウィンドウクラスを定義して Windows に登録します。ウィンドウクラスはオブジェクト指向プログラミングのオブジェクトやクラスと似ており，同一種類のコントロールのインスタンス間で共有される情報を含んでいます。新しいウィンドウクラスは既存のウィンドウクラスに基づいて作成できます。この方法をサブクラス化といいます。次に，標準 Windows コントロールと同様にカスタムコントロールをダイナミックリンクライブラリ（DLL）に入れ，そのコントロールへのインターフェースを用意します。

既存のオブジェクト（たとえば Windows コントロール）を，ユーザープログラムから使用できるようにコンポーネントとして定義することを，オブジェクトを包み込むようにコードを記述することから「ラッピング」と呼び，そのようなコンポーネントをラッパーコンポーネント（あるいは単に「ラッパー」）と呼びます。Delphi では，既存のウィンドウクラスの周りにコンポーネントの「ラッパー」を作成できます。このため，Delphi アプリケーションで使用するカスタムコントロールがすでに存在している場合，そのコントロールやそこから派生したコントロールを使用して，Delphi コンポーネントを作成できます。

Windows コントロールをサブクラス化する技法の例については，標準の Windows コントロールを表す STDCTLS ユニットのコンポーネント（TEdit など）を参照してください。


Creating nonvisual components
Creating nonvisual components1113009

Section topics 	参照

非ビジュアルコンポーネントは，データベース（TDataSet）やシステムタイマ（TTimer）などの要素のインターフェースとして，またダイアログボックス（TCommonDialog とその下位コンポーネント）のプレースホルダとして使われます。開発するコンポーネントのほとんどがビジュアルコンポーネントになるでしょう。非ビジュアルコンポーネントは，すべてのコンポーネントの抽象基本クラスである TComponent から直接派生させることができます。


What goes in a component?
What goes in a component?1113010

Section topics 	参照

コンポーネントを Delphi 環境における信頼性の高い要素にするために，コンポーネントの設計時にいくつかの規則に従う必要があります。この節では，以下の事項について説明します。

依存関係の除去

プロパティ，イベント，メソッド

グラフィックのカプセル化

登録


Removing dependencies
Removing dependencies1113011

Section topics 	参照

コンポーネントの有用性を高める 1 つの特性は，コンポーネントがコード内の任意の場所で実行できる処理への制限がないことです。コンポーネントの性質は，さまざまな組み合わせ，順序，状況において，アプリケーションに組み入れるのに適しています。前処理を必要とせず，あらゆる状況で機能するようなコンポーネントを設計しなければなりません。

依存関係除去の好例として，TWinControl の Handle プロパティがあります。Windows アプリケーションを作成したことがあればわかるように，CreateWindow という API 関数を呼び出してウィンドウかコントロールを作成する前に，そのウィンドウやコントロールにアクセスすることはできません。これは，プログラムを実行する際に最もエラーを起こしやすい点の 1 つです。Delphi ウィンドウコントロールでは，ユーザーはこの点について考慮する必要はありません。ウィンドウハンドルが必要なときは常にそのハンドルが有効だからです。コントロールは，ウィンドウハンドルを表すプロパティを参照すれば，そのウィンドウが作成済みであるかどうかを検査できます。ハンドルが有効でない場合は，コントロールはウィンドウを作成してハンドルを返します。こうして，アプリケーションのコードが Handle プロパティをアクセスしたときは，常に有効なハンドルを得られることが保証されます。

コンポーネントでは，ウィンドウの作成などの処理が自動的に行われるので，開発者は本来の作業に専念できます。ウィンドウハンドルを API 関数に渡す前に，あらかじめハンドルがあるかどうかを確認したり，ウィンドウを作成するというような作業は必要ありません。アプリケーション開発者は，誤った状態にならないように絶えずチェックする必要はなく，意図したとおりに処理が行われることを確信できます。

依存関係を持たないコンポーネントを作成するには，時間がかかるかもしれませんが，そのような時間は一般的に有意義なものです。なぜなら，それによってアプリケーション開発者が単調な作業を繰り返し行う必要がなくなるだけでなく，マニュアルの作成やサポートにかかる負担が減少するからです。


Properties, events, and methods
Properties, events, and methods1113012

Section topics 	参照

フォームデザイナで操作する目に見えるイメージであるという点を除いて，コンポーネントの重要な要素は，プロパティ，イベント，メソッドです。このマニュアルではそれぞれに独立の章が割り当てられています。この節では，この 3 つの要素の使い方について説明します。

Properties1113013

アプリケーション開発者は，値の設定や読み出しができる変数のようなつもりでプロパティを扱います。コンポーネント開発者はプロパティを使用することにより，実際のデータ構造を隠蔽したり，値のアクセスに伴う特殊な処理を定義できます。

プロパティの使用によって得られる利点は以下のとおりです。

設計時にプロパティを使用できる
これにより，アプリケーション開発者はコードを記述せずに，プロパティの初期値を設定，変更できます。

プロパティが変更されるたびに，値や形式を検査できる
設計時に入力を検証することで，エラーを防止できます。

必要なときにコンポーネントが適切な値を構築できる
よくあるエラーは，宣言や初期化がされていない変数を参照することです。データをプロパティにすれば，値が常に代入されることを保証できます。

プロパティを使うと，単純で一定したインターフェースのもとで内部データを隠蔽できる
プロパティでデータを扱うと，データの内部構造が変わってもコンポーネントを使う開発者とのインターフェースを変えずに済みます。

「プロパティの作成」では，コンポーネントにプロパティを追加する方法について説明します。

Events1113014

イベントはアプリケーション開発者に対し，コードの特定のブロックを実行時の特定の出来事（マウス操作やキー入力など）に結び付けるためのフックを与えます。イベントが発生すると実行されるコードをイベントハンドラといいます。

イベントを使うと，アプリケーション開発者は新しいコンポーネントを定義しなくても，さまざまな入力に対する応答を指定できます。

「イベントの作成」では，標準のイベントを実装したり，新しいイベントを追加する方法について説明してあります。

Methods1113015

クラスメソッドは，クラスの特定のインスタンスではなくクラスに作用する手続きと関数です。たとえば，あらゆるコンポーネントのコンストラクタメソッド（Create）はクラスメソッドです。コンポーネントメソッドは，コンポーネントのインスタンスそのものに作用する手続きと関数です。アプリケーション開発者はメソッドを使って，コンポーネントが特定の動作を実行するよう指示したり，どのプロパティにもない値を取得したりします。

メソッドはコードの実行を必要とするので，呼び出せるのは実行時だけです。メソッドは以下のような点で役に立ちます。

メソッドは，コンポーネントの機能をデータが存在するのと同じオブジェクトにカプセル化する

メソッドは，一定した単純なインターフェースのもとで複雑な手続きを隠蔽できる。アプリケーション開発者はあるコンポーネントの AlignControls メソッドを，その機能やほかのコンポーネントの AlignControls メソッドとの相違を知らなくても呼び出せる

メソッドを使うと，複数のプロパティを単一の呼び出しで更新できる

「メソッドの作成」では，コンポーネントにメソッドを追加する方法が説明してあります。


Graphics encapsulation
Graphics encapsulation1113016

Section topics 	参照

Delphi では，多様なグラフィックツールをキャンバス内にカプセル化することにより，Windows のグラフィックを簡単にします。キャンバスはウィンドウやコントロールの描画面で，ペン，ブラシ，フォントなどのほかのクラスも含んでいます。キャンバスは Windows のデバイスコンテキストとよく似ていますが，Windows のデバイスコンテキストと違う点は，キャンバスでは後始末が自動的に行われるということです。

Windows グラフィックアプリケーションを開発したことがあれば，使用可能なデバイスコンテキストの数についての制限や，グラフィックオブジェクトを廃棄するにはその前にオブジェクトを当初の状態に戻しておかなければならないことなど，Windows のグラフィックデバイスインターフェース（GDI）がさまざまな規則を開発者に課すことをご存じでしょう。

Delphi では，そうした規則にわずらわされることはありません。フォームやほかのコンポーネントに描画する場合には，コンポーネントの Canvas プロパティを使用します。ペンやブラシをカスタマイズする場合には，色やスタイルを設定します。設定が終了すると，リソースの破棄は Delphi が行います。アプリケーションが同じ種類のリソースを頻繁に使用する場合は，Delphi はリソースが再作成されないようにリソースをキャッシュに入れておきます。

もちろん今までのように Windows GDI にも全面的にアクセスできます。しかし，Delphi コンポーネントのキャンバスを使用する方が，コードが簡単になり実行速度も上がります。グラフィック機能についての詳細は，「コンポーネントでのグラフィックの使い方」で説明します。


Registration Overview
Registration1113017

Section topics 	参照

コンポーネントを Delphi IDE にインストールするには，あらかじめそのコンポーネントを登録する必要があります。登録とは，そのコンポーネントのコンポーネントパレット内の表示位置を Delphi に指示することです。また，Delphi がコンポーネントをフォームファイルに格納する方法もカスタマイズできます。登録については「コンポーネントの登録」で説明します。


Creating a new component
Creating a new component1113018

Section topics 	参照

コンポーネントを作成するプロセスは以下の 6 つの段階にまとめられます。

1.	新しいコンポーネント用のユニットを作成する

2.	既存のコンポーネント型からコンポーネントを派生させる

3.	プロパティ，メソッド，イベントを追加する

4.	コンポーネントを Delphi に登録する

5.	開発したコンポーネントと，そのコンポーネントのプロパティ，メソッド，イベントについてヘルプファイルを作成する

6.	コンポーネントを Delphi IDE にインストールできるように，パッケージ（特殊なダイナミックリンクライブラリ）を作成する

作成プロセスが終了したとき，完成したコンポーネントには以下のファイルが含まれています。

パッケージファイル（.DPL）またはパッケージコレクションファイル（.DPC)

コンパイル済みパッケージファイル（.DCP）

コンパイル済みユニット（.DCU）

パレットビットマップ（.DCR）

ヘルプファイル（.HLP）

ヘルプキーワードファイル（.KWF）

ヘルプファイルはオプションですが，ヘルプファイルがあれば，開発したコンポーネントはさらに使いやすいものになります。

新しいコンポーネントを作成する場合に必要な基本手順がいくつかあります。以下に手順を示します。このマニュアルのほかの例はすべて，この手順についての知識を前提にして記述されています。

新しいコンポーネントを作成する方法には，以下の 2 つがあります。

コンポーネントウィザードを使う

コンポーネントを手作業で作成する

いずれかの方法で，最小限の機能を持つコンポーネントが作成されます。作成されたコンポーネントは，コンポーネントパレットにインストールできます。インストール後，その新しいコンポーネントをフォームに追加して，設計時と実行時の両方についてテストすることができます。そのコンポーネントにさらに多くの機能を追加して，コンポーネントパレットを更新し，再びテストすることもできます。


Using the Component wizard
Using the Component wizard1113019

Section topics 	参照

コンポーネントウィザードは，コンポーネントの作成の初期段階を簡略化します。コンポーネントウィザードを使う場合，以下の項目を指定する必要があります。

コンポーネントの派生元のクラス

新しいコンポーネントのクラス名

コンポーネントを表示するコンポーネントパレットのページ

コンポーネントを作成するユニット名

ユニットがある検索パス

コンポーネントを入れるパッケージ名

コンポーネントエキスパートは，コンポーネントを手作業で作成する場合と同様に，以下の 3 つの作業を行います。

ユニットの作成

コンポーネントの派生

コンポーネントの登録

ただし，コンポーネントウィザードでは，既存のユニットにコンポーネントを追加することはできません。既存のユニットにコンポーネントを追加する場合は，手作業が必要です。

コンポーネントエキスパートを開くには，以下のどちらかを行います。

［Component｜New Component］を選択する

［ファイル(F)｜新規作成(N)］を選択し，［Component］をダブルクリックする

コンポーネントウィザードで各項目に値を入力します。

1.	［Ancestor Type］項目で，新しいコンポーネントの派生元のクラスを指定します。

2.	［Class Name］項目で，新しいコンポーネントクラスの名前を指定します。

3.	［Palette Page］項目で，新しいコンポーネントをインストールするコンポーネントパレットのページを指定します。

4.	コンポーネントクラスを宣言するユニットの名前を指定します。

5.	ユニットが検索パスにない場合，［Search Path］項目の検索パスを必要に応じて編集します。

コンポーネントを新しいパッケージに入れる場合でも既存のパッケージに入れる場合でも，［Install］をクリックし，表示されるダイアログボックスでパッケージを指定します。これによりパッケージエディタが開き，パッケージの自動コンパイルおよびコンポーネントパレットへの新しいコンポーネントのインストールを求めるダイアログボックスが表示されます。パッケージエディタについての詳細は，『ユーザーズガイド』に記載されています。

警告	名前が「custom」で始まる VCL クラス（TCustomControl など）からコンポーネントを派生させる場合，オリジナルのコンポーネントの抽象メソッドをオーバーライドし終わるまで，新しいコンポーネントをフォームに配置しないでください。Delphi では，抽象プロパティまたは抽象メソッドを含むクラスのインスタンスオブジェクトは作成できません。

ユニットのソースコードを表示するには，パッケージエディタに表示されているファイル名をダブルクリックします。クラス宣言と Register 手続きの入った新しいユニットが作成され，Delphi のすべての標準ユニットを含む uses 節が追加されます。ユニットは次のようになります。

unit MyControl;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type

TMyControl = class(TCustomControl)

private

{ private 宣言 }

protected

{ protected 宣言 }

public

{ public 宣言 }

published

{ published 宣言 }

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents('Samples', [TMyControl]);

end;

end.


Creating a component manually
Creating a component manually1113020

Section topics 	参照

新しいコンポーネントを作成する最も簡単な方法は，コンポーネントウィザードを使用することですが，同じことを手作業でも行えます。

コンポーネントを手作業で作成するには，以下の 3 つの段階があります。

1.	ユニットファイルの作成

2.	コンポーネントの派生

3.	コンポーネントの登録


Creating a unit file
Creating a unit file1113021

Section topics 	参照

ユニットとは，個別にコンパイルされる Object Pascal コードのモジュールのことです。Delphi では，ユニットはさまざまな目的のために使われます。すべてのフォームは独自のユニットを持ち，ほとんどのコンポーネント（またはそのグループ）も独自のユニットを持っています。

コンポーネントの作成に当たっては，そのコンポーネント用の新しいユニットを作成するか，または既存のユニットにその新しいコンポーネントを追加します。

ユニットを作成するには，［ファイル(F)｜新規作成(N)］を選択し，［Unit］をダブルクリックします。Delphi は新しいユニットファイルを作成し，コードエディタでそのファイルを開きます。

既存のユニットを開くには，［ファイル(F)｜ファイルを開く(O)］を選択して，コンポーネントに追加したいソースコードユニットを選びます。

メモ	既存のユニットにコンポーネントを追加する場合には，ユニットにはコンポーネントコードだけが入っていることを確認してください。たとえば，フォームが入っているユニットにコンポーネントコードを追加すると，コンポーネントパレットでエラーが発生します。

コンポーネント用の新しいユニットか既存のユニットがあれば，コンポーネントクラスを派生させることができます。


Deriving the component
Deriving the component1113022

Section topics 	参照	例

すべてのコンポーネントは，TComponent，あるいは TControl や TGraphicControl などの TComponent を特殊化した下位クラスから派生したクラスです。また，他の既存のコンポーネントクラスから派生したものもあります。

コンポーネントを派生させるには，そのコンポーネントを入れるユニットのインターフェース部にオブジェクト型宣言を記述します。


An example of deriving a component
An example of deriving a component1113023

Section topics 	参照

コンポーネントの基本クラスである TComponent を直接継承した非ビジュアルコンポーネントを作成するには，コンポーネントユニットのインターフェース部に次のクラス宣言を記述します。

type

TNewComponent = class(TComponent)

end;

この新しいコンポーネントは，このままでは TComponent と同じことしか行いません。ただ，そこに新しいコンポーネントを構築するためのフレームワークが作成されたことになります。


Registering the component
Registering the component1113024

Section topics 	参照	例

登録は，Delphi のコンポーネントライブラリに追加するコンポーネントと，そのコンポーネントを表示するコンポーネントパレットのページを Delphi に知らせるだけです。登録についての詳細は「コンポーネントの登録」を参照してください。

コンポーネントを登録する手順は次のとおりです。

1.	Register という手続きを，そのコンポーネントユニットのインターフェース部に記述します。

procedure Register;

すでにコンポーネントが入っているユニットにコンポーネントを追加する場合には，そのユニットには手続き Register がすでに宣言されています。したがって，宣言の追加は必要ありません。

2.	ユニットの実現部に手続き Register を記述して，登録するコンポーネントのそれぞれについて RegisterComponents を呼び出します。手続き RegisterComponents は，2 つのパラメータ（コンポーネントパレットのページ名とコンポーネント型の集合）を使用します。既存の登録プロセスに新しいコンポーネントを追加する場合には，既存の文中のコンポーネントの集合に新しいコンポーネントを追加するか，RegisterComponents を呼び出す新しい文を追加します。


An example of registering a component
An example of registering a component1113025

Section topics 	参照

TMyControl という名前のコンポーネントを登録して，パレットの Samples ページに配置するには，TMyControl の宣言を記述したユニットに以下のように手続き Register を追加します。

procedure Register;

begin

 RegisterComponents('Samples', [TNewControl]);

end;

この Register 手続きは TMyControl をコンポーネントパレットの Samples ページに配置します。

コンポーネントの登録が終われば，そのコンポーネントをパッケージ（「パッケージの作成」を参照）にコンパイルし，コンポーネントパレットにインストールできます。


Testing uninstalled components
Testing uninstalled components1113026

Section topics 	参照	例

コンポーネントをコンポーネントパレットにインストールする前に，そのコンポーネントの実行時の動作をテストできます。このテストは新たに作成したコンポーネントのデバッグに役立ちます。このテクニックは，コンポーネントパレットに表示するかどうかにかかわらず，すべてのコンポーネントに対して使用できます。

コンポーネントをパレットから選択しフォームに配置したときに，Delphi が実行するアクションをエミュレートすることにより，インストールされていないコンポーネントをテストします。

インストールされていないコンポーネントをテストする手順は次のとおりです。

1.	コンポーネントのユニットの名前を，フォームユニットの uses 節に追加します。

2.	そのコンポーネントを表すフォームに，オブジェクトフィールドを追加します。

これは，コンポーネントを開発者が手作業で追加する場合と，Delphi が追加する場合との大きな相違点です。開発者は，フォームの型宣言の一番下の public 部にオブジェクトフィールドを追加します。これに対して Delphi は，型宣言の上方の Delphi 自身で管理している部分に追加します。

フォームの型宣言の Delphi が管理する部分には，決してフィールドを追加しないでください。型宣言のこの部分の項目は，フォームファイルに格納されている項目に対応しています。存在していないコンポーネントの名前がフォームに追加されると，フォームファイルが無効になってしまう恐れがあります。

3.	フォームの OnCreate イベントにハンドラを結び付けます。

4.	フォームの OnCreate ハンドラでコンポーネントを構築します。

コンポーネントのコンストラクタを呼び出した場合には，そのコンポーネントのオーナー（適切な時期にそのコンポーネントを廃棄する責任を持つコンポーネント）を指定するパラメータを渡す必要があります。これについては，ほとんどすべての場合に， Self をオーナーとして渡すことになります。メソッドでは，Self はそのメソッドが所属するオブジェクトへの参照を表します。フォームの OnCreate ハンドラでは，Self はフォームへの参照です。

5.	コンポーネントの Parent プロパティを指定します。

Parent プロパティの設定は，必ずコンポーネントを構築した直後に行います。コンポーネントの親は，そのコンポーネントをビジュアルに含んでいるようなコンポーネントです。多くの場合，コンポーネントが表示されるのはフォーム自身になりますが，グループボックスやパネルの場合もあります。通常，Parent は Self，つまりフォームに設定します。必ず，Parent はコンポーネントのほかのプロパティを設定する前に設定します。

警告	作成するコンポーネントがコントロールではない場合（つまり TControl またはその派生クラスから派生していない場合），このステップは飛ばしてください。誤って（コンポーネントの Parent ではなく）フォームの Parent プロパティを Self に設定してしまうと，オペレーティングシステムで問題が発生することがあります。

6.	必要に応じて，ほかのコンポーネントプロパティを設定します。


An example of testing uninstalled components
An example of testing uninstalled components1113027

Section topics 	参照

MyControl と命名されたユニットで，TMyControl 型の新しいコンポーネントをテストすることを考えます。新しいプロジェクトを作成し，前述の 1～6 の手順にしたがって，次のようなフォームユニットを作成します。

unit Unit1;

interface

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

Forms, Dialogs, MyControl;	{1. NewTest を uses 節に追加}

type

 TForm1 = class(TForm)

procedure FormCreate(Sender: TObject);	{3. OnCreate にハンドラを結び付ける}

private

{ private 宣言 }

public

{ public 宣言 }

MyControl1: TMyControl1;	{2. オブジェクトフィールドを追加}

end;

var

 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

begin

 MyControl1 := TMyControl.Create(Self);	{4. コンポーネントを構築}

MyControl1.Parent := Self;	{5. Parent プロパティを設定}

MyControl1.Left := 12;	{6. ほかのプロパティを設定 ... }

...	{...必要に応じてほかのプロパティも設定}

end;

end.


See also1113028

TCustomControl

TCustomProvider

TCustomImageList

TCustomContentProvider

TCustomRemoteServer

TCustomSocket

TCustomLabel

TCustomComboBox

TCustomEdit

TCustomHotKey

TCustomListBox

TCustomListView

TCustomStaticText

TCustomTabControl

TCustomTreeView

TCustomUpDown

TCustomForm

TCustomCheckBox

TCustomGrid

TCustomGroupBox

TCustomPanel

TCustomDBGrid

TCustomOutline

TCustomRadioGroup

TCustomMaskEdit

TCustomMemo

TCustomRichEdit

TCustomMemoryStream

TWinControl

TCustomControl

TCustomControl

TDataSet

TComponent

TTimer

TCommonDialog


Object-oriented programming for component writers
Object-oriented programming for component writers1112001

Section topics	参照

クラスはデータとコードから構成されます。コンポーネント開発者だけでなく，普通の Delphi アプリケーションの開発者もオブジェクトを常に扱っています。

新しいコンポーネントを作成する場合，アプリケーション開発者には必要のない方法でクラスを取り扱います。また，コンポーネントの内部機構を，そのコンポーネントを使う開発者から隠蔽するようにします。コンポーネントに適した上位クラスを選択し，開発者が必要とするプロパティとメソッドだけを提供するインターフェースを設計して，この章で示すその他のガイドラインに従うことにより，用途が広く，繰り返し使えるコンポーネントを作成できます。

コンポーネントの作成を開始する前に，オブジェクト指向プログラミング（OOP）一般について，次の項目を理解しておく必要があります。

新しいオブジェクトの作り方

上位クラスと下位クラス

アクセスの制御

メソッドのディスパッチ

抽象クラスメンバー

クラスとポインタ


Creating new classes
Creating new classes1112002

Section topics	参照

コンポーネント開発者は新しいクラスを作成します。それに対して，アプリケーション開発者はクラスのインスタンスを操作します。ここに，コンポーネント開発者とアプリケーション開発者との相違点があります。

クラスは基本的に１つの型です。プログラマは常に型とインスタンスを使っています。ただ，こうした用語を一般には使わないだけです。たとえば，integer のような型の変数を作成します。一般にクラスは，単純なデータ型よりも複雑ですが，使い方は同じです。同じ型に属する各インスタンスにさまざまな値を指定することにより，きわめて多様な処理を実現できます。

たとえば，よくあることですが，一方は OK というラベルを持ち，他方は Cancel というラベルを持つ 2 つのボタンをあるフォーム上に作成するとします。この場合，2 つのボタンは両方とも TButton クラスのインスタンスになります。しかし，Caption プロパティに異なる値を指定し，さらに OnClick イベントに異なるハンドラを設定することにより，この 2 つのインスタンスにまったく異なった機能を与えます。


Deriving new classes
Deriving new classes1112003

Section topics	参照

新しいクラスを派生させるのは，以下の 2 つの理由があります。

クラスのデフォルトを変更する

クラスに新しい機能を追加する

どちらの場合も，目標は再利用可能なオブジェクトの作成です。再利用を考慮してコンポーネントを設計すれば，後々，多くの作業を省けます。開発するクラスには，有用なデフォルト値を与えて，同時にカスタマイズも可能にしておきます。


Changing class defaults to avoid repetition
Changing class defaults to avoid repetition1112004

Section topics

たいていのプログラマは反復作業は避けたいものです。たとえば，同じコードを何度も繰り返し記述していることに気付いた場合には，そのコードをサブルーチンや関数として独立させるか，またはさらにルーチンをライブラリ化して多くのプログラムで使用できるようにします。コンポーネントについても同じ考え方がそのまま当てはまります。同じプロパティを繰り返し変更したり，同じメソッドを繰り返し呼び出しているような場合には，それをデフォルトで行う新しいコンポーネントを作成すべきです。

たとえば，アプリケーションを作成するたびに，特定の操作をするためのダイアログボックスを追加していることがあります。同じダイアログボックスを毎回作成するのはそれほど困難なことではありませんが，それは不必要な作業です。なぜなら，最初に 1 度だけダイアログボックスを設計してプロパティを設定し，それに関連付けたラッパーコンポーネントをコンポーネントパレットにインストールすることができるからです。ダイアログボックスを再使用可能なコンポーネントにすれば，反復作業を減少できるだけでなく，標準化が推進され，ダイアログボックスを再作成することによりエラーが発生する可能性が減少します。

メモ	既存のコンポーネントのパブリッシュプロパティだけを変更する場合や，コンポーネントまたはコンポーネントグループの特定のイベントハンドラを保存する場合は，コンポーネントテンプレートを作成すると作業が簡単になります。詳細は『ユーザーズガイド』を参照してください。


Adding new capabilities to a class
Adding new capabilities to a class1112005

Section topics

新しいコンポーネントを作成する一般的な理由の１つは，既存のコンポーネントが備えていない機能の追加です。この場合には，新しいコンポーネントを既存のコンポーネントから派生させるか，TComponent や TControl などの抽象基本クラスから派生させるかのどちらかの方法を採ります。

新しいコンポーネントは，必要な機能に最も近い機能のサブセットを備えたクラスから派生させます。クラスに対して機能を追加することはできますが，クラスから機能を取り去ることはできません。したがって，既存のコンポーネントクラスに，開発するコンポーネントに含めたくないプロパティが入っている場合には，そのコンポーネントの上位クラスから派生させる必要があります。

たとえば，リストボックスに機能を追加する場合には，TListBox からコンポーネントを派生させることができます。ただし，ある新しい機能を追加するだけでなく，標準リストボックスのある種の機能は除去したいという場合には，TListBox の上位クラスである TCustomListBox からコンポーネントを派生させます。この場合，リストボックスの機能のうち必要なものだけ再作成します。そして，新しい機能を追加します。


Declaring a new component class
Declaring a new component class1112006

Section topics	参照	例

標準コンポーネントのほかに，Delphi では，新しいコンポーネントを派生させるための基礎として設計された抽象クラスが数多く用意されています。「コンポーネントの作成」に，コンポーネント開発で派生元として使用できるクラスを示します。

新しいコンポーネントクラスを宣言するには，そのコンポーネントのユニットファイルにクラス宣言を記述します。


An example of declaring a new component class
An example of declaring a new component class1112007

Section topics

簡単なグラフィックコンポーネントの宣言を次に示します。

type

TSampleShape = class(TGraphicControl)

end;


Ancestors, descendants, and class hierarchies
Ancestors, descendants, and class hierarchies1112008

Section topics	参照

アプリケーション開発者から見ると，すべてのコントロールはプロパティ Top および Left を持っています。このプロパティは，そのコントロールのフォームでの位置を示します。この 2 つのプロパティは，共通の上位クラスである TControl から継承されているのですが，アプリケーション開発者はそのようなことを意識する必要はありません。しかし，コンポーネントを作成する場合には，コンポーネントにどのクラスを継承させるか決めなければなりません。また，継承した機能を再作成することなく利用できるように，開発するコントロールが継承する機能について把握しておく必要があります。

コンポーネントの派生元となるクラスを，そのコンポーネントの直接上位クラスといいます。各コンポーネントの継承元は，そのコンポーネントの直接上位クラスや，直接上位クラスの直接上位クラスという具合になります。コンポーネントの継承元となるすべてのクラスを，そのコンポーネントの上位クラスといいます。この場合コンポーネントは，その上位クラスからみて下位クラスになります。

1 つのアプリケーションでは，すべての上位下位の関係が 1 つのクラス階層を構成します。階層がより下位のクラスほど多くの機能が入っています。あるクラスはその上位クラスの機能をすべて継承したうえで，新しいプロパティやメソッドを追加したり，既存のプロパティやメソッドを再定義するからです。

新しいコンポーネントを定義する場合，直接上位クラスを指定しなかったときは，デフォルトの上位クラスである TObject から派生します。TObject はビジュアルコンポーネントライブラリのすべてのクラスの上位クラスです。

どのオブジェクトからフォームを派生させるかを決める基本ルールは単純です。新しいオブジェクトに入れたい内容がもっとも多く含まれていて，なおかつ新しいオブジェクトに必要のない内容はいっさい入っていないオブジェクトを選ぶようにします。オブジェクトの内容は，いつでも追加することはできますが，継承した内容を取り除くことはできないからです。


Controlling access
Controlling access1112009

Section topics	参照

プロパティ，メソッド，項目へのアクセス制御には 5 つのレベルがあります。このアクセス制御は可視性ともいいます。可視性により，どのコードがクラスのどの部分にアクセスできるかが決まります。可視性を指定することにより，コンポーネントへのインターフェースを定義します。

表に，可視性のレベルを，アクセスの制約がもっとも厳しいレベルからもっとも緩いレベルの順に示します。

保護レベル	意味	使用目的
private	そのクラスが定義されているユニットのコードからのみアクセスできる	実装の詳細の隠蔽
protected	そのクラスおよび下位クラスが定義されているユニットのコードからアクセスできる	開発者用インターフェースの定義
public	すべてのコードからアクセスできる	実行時インターフェースの定義
	すべてのコードからアクセスできる。オートメーション型情報が生成される	OLE オートメーションのみ
published	すべてのコード，およびオブジェクトインスペクタからアクセスできる	設計時インターフェースの定義
メンバーは，それが定義されているクラス内だけで使えるようにする場合は private として宣言します。定義されているクラスとその下位クラスだけで使えるようにする場合は，protected として宣言します。ただし，メンバーがユニットファイル内のどこかで使える場合，そのメンバーはユニットファイル内のどこででも使えることに注意してください。したがって，同一ユニット内に 2 つのクラスを定義する場合，そのクラスは互いの private のメソッドにアクセスできます。上位クラスから別のユニットにクラスを派生させる場合，新しいユニット内のすべてのクラスはその上位クラスの protected のメソッドにアクセスできます。


Hiding implementation details
Hiding implementation details1112010

Section topics	参照	例

クラスのある部分を private として宣言すると，その部分は，そのクラスのユニットファイル以外のコードからは見えなくなります。その宣言を行ったユニット内のコードからは，public の部分と同じようにアクセスできます。


An example of hiding implementation details
An example of hiding implementation details1112011

Section topics

次の例では，あるフィールドを private として宣言して，アプリケーション開発者から隠す方法を示しています。コードリストの 2 つのフォームユニットには，それぞれ OnCreate イベント用のハンドラがあります。各ハンドラはプライベートなフィールドに値を代入します。コンパイラは，フィールドを宣言したフォーム内での代入しか許可しません。

unit HideInfo;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs;

type

TSecretForm = class(TForm)	{新しいフォームの宣言}

procedure FormCreate(Sender: TObject);

private	{private 部の宣言}

FSecretCode: Integer;	{プライベートなフィールドの宣言}

end;

var

 SecretForm: TSecretForm;

implementation

procedure TSecretForm.FormCreate(Sender: TObject);

begin

FSecretCode := 42;	{正しくコンパイルできる}

end;

end.	{ユニットの終わり}

unit TestHide;	{メインのフォームファイル}

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs,

HideInfo;	{TSecretForm のあるユニット}

type

TTestForm = class(TForm)

procedure FormCreate(Sender: TObject);

end;

var

TestForm: TTestForm;

implementation

procedure TTestForm.FormCreate(Sender: TObject);

begin

SecretForm.FSecretCode := 13;	{コンパイラは「Field identifier expected」というエラーを表示する}

end;

end.	{ユニットの終わり}

HideInfo ユニットを使用するプログラムは TSecretForm 型のオブジェクトは使用できますが，そのオブジェクトの FSecretCode フィールドにはアクセスできません。


Defining the component writer's interface
Defining the component writer's interface1112012

Section topics	参照

クラスのある部分を protected として宣言すると，クラス自身およびその下位クラスと，ユニットファイルを共有するその他のクラスだけにその部分が見えるようになります。

protected 宣言を使うと，クラスに対してコンポーネント開発者用のインターフェースを定義できます。protected の部分には，アプリケーションユニットはアクセスできませんが，派生クラスはアクセスできます。つまり，コンポーネント開発者は，アプリケーション開発者に詳細を公開しなくても，クラスの動作を変更できます。


Defining the runtime interface
Defining the runtime interface1112013

Section topics	参照	例

クラスで public として宣言した部分は，そのクラス全体にアクセスするすべてのコードから見えるようになります。

public 部は，実行時にすべてのコードで使用できます。したがって，クラスはその public 部によって実行時インターフェースが定義されることになります。実行時の入力に依存する読み出し専用のプロパティなど，設計時には無効な項目は，実行時インターフェースに宣言します。また，アプリケーション開発者によって呼び出されるメソッドも，public として宣言しなければなりません。


An example of defining the runtime interface
An example of defining the runtime interface1112014

Section topics

次の例は，コンポーネントの実行時インターフェースの部分に宣言された 2 つの読み出し専用プロパティを示します。

type

TSampleComponent = class(TComponent)

private

FTempCelsius: Integer;	{実装の詳細を private 部に記述}

function GetTempFahrenheit: Integer;

public

property TempCelsius: Integer read FTempCelsius;	{プロパティを public 部に記述}

property TempFahrenheit: Integer read GetTempFahrenheit;

end;

...

function TSampleComponent.GetTempFahrenheit: Integer;

begin

Result := FTempCelsius * 9 div 5 + 32;

end;


Defining the design-time interface
Defining the design-time interface1112015

Section topics	参照	例

クラスで published として宣言した部分は，パブリックになり，さらに実行時型情報が生成されます。この実行時型情報により，オブジェクトインスペクタでプロパティやイベントにアクセスできるようになります。

published 部はオブジェクトインスペクタに表示されます。つまり，クラスの published 部によって，そのクラスの設計時インターフェースが定義されることになります。クラスの各側面のうち，アプリケーション開発者が設計時にカスタマイズする可能性のある部分はすべて設計時インターフェースに含めます。これに対して，実行時環境の特定の情報に依存するすべてのプロパティは，設計時インターフェースには含めません。

読み出し専用プロパティはアプリケーション開発者が直接値を代入できないので，設計時インターフェースに含めません。読み出し専用プロパティは published ではなく public と宣言します。


An example of defining the design-time interface
An example of defining the design-time interface1112016

Section topics

次の例は，パブリッシュに設定された Temperature プロパティを示します。このプロパティはパブリッシュに設定されているため，設計時にオブジェクトインスペクタに表示されます。

type

TSampleComponent = class(TComponent)

private

FTemperature: Integer;	{実現の詳細は private 部に記述}

published

property Temperature: Integer read FTemperature write FTemperature;	{書き込み可能！}

end;


Dispatching methods
Dispatching methods1112017

Section topics

メソッドが呼び出されたときにそのメソッドをどこで実行するかをプログラムが決めることを，ディスパッチといいます。メソッドを呼び出すコードは，手続きや関数を呼び出すコードのように記述します。しかし，クラスにはメソッドをディスパッチするための 3 通りの方法があります。

3 種類のメソッドディスパッチは次のとおりです。

静的

仮想

動的


Static methods
Static methods1112018

Section topics

特に指定しなければ，すべてのメソッドは静的メソッドになります。静的メソッドは，普通の手続きや関数と同じように動作します。コンパイラはメソッドの正確なアドレスを決定し，コンパイル時にそのメソッドをリンクします。

静的メソッドの第一の利点は，ディスパッチが高速であることです。コンパイラは静的メソッドの正確なアドレスを決定して，メソッドを直接リンクできます。これに対して仮想メソッドと動的メソッドでは，実行時に間接的な方法でメソッドのアドレスを探す必要があるため多少遅くなります。

静的メソッドは下位クラスに継承されても変化しません。静的メソッドを含むクラスを宣言し，そのクラスから新しいクラスを派生させた場合，派生クラスはまったく同じメソッドを同じアドレスで共有します。つまり，静的メソッドはオーバーライドできません。どのクラスで呼び出された場合でも，静的メソッドは常にまったく同じ処理を行います。派生クラス内で上位クラスの静的メソッドと同じ名前のメソッドを宣言した場合，さらにそのクラスから派生したクラスの中から呼び出した時のみ継承メソッドが新しいメソッドに置き換えられます。

次に示すコードでは，第 1 のコンポーネントが 2 つの静的メソッドを宣言し，さらに，第 2 のコンポーネントが 2 つの静的メソッドを同じ名前で宣言しています。その結果，第 2 のコンポーネントの 2 つのメソッドが，第 1 のコンポーネントから継続されたメソッドを置換します。

type

TFirstComponent = class(TComponent)

procedure Move;

procedure Flash;

end;

TSecondComponent = class(TFirstComponent)

procedure Move;	{同じ宣言だが継承メソッドではない}

function Flash(HowOften: Integer): Integer;	{これも異なる}

end;


Virtual methods
Virtual methods1112019

Section topics	参照

仮想メソッドでは，静的メソッドよりもディスパッチのメカニズムが複雑ですが柔軟性があります。仮想メソッドは下位クラスで再定義できますが，その場合でも上位クラスで呼び出せます。仮想メソッドのアドレスはコンパイル時には決まりません。そのかわりに，仮想メソッドが定義されているクラスが実行時にアドレスを調べます。

メソッドを仮想にするには，メソッド宣言の後に virtual 指令を追加します。virtual 指令は，そのオブジェクトの仮想メソッドテーブル（VMT）にエントリを作成します。VMT には，そのオブジェクト型のすべての仮想メソッドのアドレスが格納されます。

既存のクラスから新しいクラスを派生させると，その新しいクラスにはそれ自身の VMT が与えられます。この VMT には，上位クラスから継承したすべてのエントリに加えて，新しいクラスで新たに宣言されたすべての仮想メソッドのエントリが格納されます。


Overriding methods
Overriding methods1112020

Section topics	参照	例

メソッドのオーバーライドは，メソッドの置換ではありません。メソッドのオーバーライドとは，そのメソッドを拡張したり，詳細化することを意味します。下位クラスは，継承した仮想メソッドをすべてオーバーライドします。

下位クラスでメソッドをオーバーライドするには，メソッド宣言の末尾に override 指令を追加します。

次の場合にメソッドをオーバーライドすると，コンパイルエラーが発生します。

上位クラスにそのメソッドが存在しない場合

上位クラスのその名前のメソッドが静的メソッドである場合

引数パラメータの数や型に関して，宣言に不一致がある場合


An example of overriding methods
An example of overriding methods1112021

Section topics

次の例では，2 つの簡単なコンポーネントの宣言を示します。第 1 のコンポーネントは，それぞれの種類のディスパッチを行う 3 つのメソッドを宣言しています。第 1 のコンポーネントから派生した第 2 のコンポーネントは，静的メソッドを置換し，仮想メソッドをオーバーライドします。

type

TFirstComponent = class(TCustomControl)

procedure Move;	{静的メソッド}

procedure Flash; virtual;	{仮想メソッド}

procedure Beep; dynamic;	{動的仮想メソッド}

end;

TSecondComponent = class(TFirstComponent)

procedure Move;	{新しいメソッド}

procedure Flash; override;	{継承されたメソッドをオーバーライド}

procedure Beep; override;	{継承されたメソッドをオーバーライド}

end;


Dynamic methods
Dynamic methods1112022

Section topics

動的メソッドは仮想メソッドと似ていますが，やや異なったディスパッチメカニズムを備えています。動的メソッドは，オブジェクトの仮想メソッドテーブルにエントリを作成しないため，オブジェクトが消費するメモリ量は減少しますが，ディスパッチにかかる時間は普通の仮想メソッドよりも少し増加します。繰り返し呼び出すメソッドや，呼び出しの実行速度が重要なメソッドの場合には，動的メソッドではなく仮想メソッドを宣言します。

オブジェクトはその動的メソッドのアドレスを格納しなければなりません。ただし，仮想メソッドテーブルにエントリを受け入れるかわりに，動的メソッドリストが別に作成されます。動的メソッドリストには，特定のクラスによって追加またはオーバーライドされたメソッドのエントリだけが入っています。これに対して仮想メソッドテーブルには，オブジェクトの仮想メソッドが，継承されたものも追加されたものも含めてすべて入っています。継承された動的メソッドをディスパッチする場合は，継承ツリーを逆方向にたどって，各上位クラスの動的メソッドリストを検索していきます。

メソッドを動的にするには，メソッド宣言の後に dynamic 指令を追加します。


Abstract class members
Abstract class members1112023

Section topics

上位クラスでメソッドを abstract として宣言した場合，下位コンポーネントでそのメソッドを再宣言して実装することにより明示しなければ，その新しいコンポーネントはアプリケーションで使えません。Delphi では，抽象メンバーを含むクラスのインスタンスは作成できません。クラスの継承部分の明示についての詳細は，「プロパティの作成」と「メソッドの作成」を参照してください。


Classes and pointers
Classes and pointers1112024

Section topics

クラスはすべて実際にはポインタであり，コンポーネントも同様です。開発者にかわってコンパイラが自動的にクラスポインタを逆参照するので，ほとんどの場合このことを考慮する必要はありません。しかし，クラスをパラメータとして渡すときは，クラスがポインタであることが重要になります。一般に，クラスは参照渡しではなく値渡しで渡します。なぜなら，クラスはもともとポインタ，つまり参照であるため，あるクラスを参照渡しで渡すことは，参照の参照を渡すことになるからです。


Creating properties
Creating properties1115001

Section topics	参照

プロパティは，コンポーネントで最も可視的な構成要素です。アプリケーション開発者は設計時に画面でプロパティを操作でき，その操作の結果はすぐにフォームデザイナでコンポーネントに反映されます。プロパティを適切に設計すれば，ユーザーにとっては使いやすく，開発者にとっては保守しやすいコンポーネントが作成できます。

この章では，開発するコンポーネントでプロパティを有効に使用するため，以下のことを説明します。

プロパティを作成する理由

プロパティの型

継承プロパティの公開

コンポーネントプロパティの定義

配列プロパティの作成

プロパティエディタの開発


Why create properties?
Why create properties?1115002

Section topics	参照

アプリケーション開発者の立場からは，プロパティは変数のようなものです。開発者は，フィールドを操作するように，プロパティの値を設定または読み出します。開発者にとって，変数では可能でプロパティでは不可能なことは，プロパティを var パラメータとしては渡せないということだけです。

以下の理由でプロパティは単純なフィールドよりも大きな能力を持っています。

プロパティはアプリケーション開発者が設計時に設定できる
実行時にのみ処理可能なメソッドと違って，開発者はプロパティによってアプリケーションを実行する前にコンポーネントをカスタマイズできます。プロパティはオブジェクトインスペクタに表示できるので，プログラマの作業は簡単になります。つまり，いくつものパラメータを処理してオブジェクトを作成するかわりに，Delphi でオブジェクトインスペクタの値を読み出せます。またオブジェクトインスペクタでは，プロパティへの代入が行われるとすぐにその代入が検証されます。

プロパティは実装の詳細を隠蔽できる
たとえば，内部に暗号化形式で格納されているデータを，プロパティの値としては暗号化されていないように見えることがあります。プロパティの値が単純な数値であっても，コンポーネントはその値を得るためにデータベースを検索したり，複雑な計算を行うことがあります。プロパティを使えば，単純な代入のように見える操作に複雑な働きをさせることができます。つまりフィールドへの代入のように見える操作を，複雑な処理を実行するメソッドの呼び出しにできます。

プロパティは仮想メソッドであり得る
アプリケーション開発者から見て単一のプロパティでも，コンポーネントによっては実装が異なる場合があります。

簡単な例は，すべてのコントロールが持つ Top プロパティです。Top への新しい値の代入は，単にその値を変更するだけの操作ではありません。コントロールを再配置して再描画します。また，プロパティの設定が及ぼす影響は，必ずしも 1 つのコンポーネントに限定されるわけではありません。あるスピードボタンの Down プロパティを True に設定すると，グループ内のほかのすべてのスピードボタンの Downプロパティは False になります。


Types of properties
Types of properties1115003

Section topics	参照

プロパティはどの型にでもできます。型によってオブジェクトインスペクタでの表示方法は異なります。オブジェクトインスペクタでは，設計時に行われたプロパティへの代入が検証されます。

プロパティの型	オブジェクトインスペクタでの扱われ方
単純型	数値，文字，文字列の各プロパティは，それぞれ数値，文字，文字列として表示される。ユーザーはプロパティの値を直接入力して編集できる
列挙型	論理型を含めて，列挙型のプロパティでは，ソースコードで定義された値が表示される。ユーザーは，値の列をダブルクリックすることで，使用可能な値を循環的に切り替えられる。また，ある列挙型プロパティのすべての値を示すドロップダウンリストも用意されている
集合型	集合型のプロパティは，1 つの集合として表示される。ユーザーは，集合を展開すれば，集合の各要素を論理値として扱える。この場合，その要素が集合に含まれている場合には True，含まれていない場合には False となる
オブジェクト型	オブジェクトであるプロパティは，独自のプロパティエディタを持つ場合がある。ただし，そのオブジェクトがその中のプロパティをパブリッシュに設定している場合は，ユーザーはオブジェクトインスペクタでオブジェクトプロパティのリストを展開して，それらを個別に編集できる。オブジェクトプロパティは必ず TPersistent を継承する
配列型	配列プロパティは，独自のプロパティエディタを備えている必要がある。オブジェクトインスペクタでの配列プロパティの編集はサポートされていない


Publishing inherited properties
Publishing inherited properties1115004

Section topics	参照	例

すべてのコンポーネントは，それぞれの上位クラスからプロパティを継承しています。既存のコンポーネントから新しいコンポーネントを派生させると，その新しいコンポーネントは直接上位コンポーネントのすべてのプロパティを継承します。抽象クラスの 1 つから派生させた場合には，継承したプロパティの多くは protected か public のいずれかになりますが，published にはなりません。

protected または public のプロパティをオブジェクトインスペクタで設計時に使えるようにするためには，そのプロパティを published として再宣言します。再宣言するためには，下位クラスの宣言部に継承したプロパティの宣言を追加します。


An example of publishing an inherited property
An example of publishing an inherited property1115005

Section topics

たとえば，TWinControl からコンポーネントを派生させると，このコンポーネントは protected の Ctl3D プロパティを継承します。新しいコンポーネントで Ctl3D を再宣言することで，保護のレベルを public か published のいずれかに変更できます。

次のコードでは，Ctl3D を published として再宣言し，設計時に処理可能にする方法を示しています。

type

TSampleComponent = class(TWinControl)

published

property Ctl3D;

end;

プロパティを再宣言する際には，プロパティ名だけを指定します。「プロパティの定義」で説明するような情報や型を指定する必要はありません。また，新しいデフォルト値を宣言でき，そのプロパティを保存するかどうかも指定できます。

再宣言では，あるプロパティに対する制約を減らすことはできますが，制約の強化はできません。つまり，protected プロパティを public プロパティにすることはできますが，public プロパティを protected として再宣言し，このプロパティを隠蔽することはできないということです。


Defining properties
Defining properties1115006

Section topics	参照

ここでは，新しいプロパティの宣言方法を示し，標準コンポーネントに関する規則を説明します。

プロパティの宣言

内部的なデータ記憶

直接アクセス

アクセスメソッド

デフォルトのプロパティ値


The property declaration
The property declaration1115007

Section topics	参照	例

プロパティはコンポーネントクラスの宣言内で宣言されます。プロパティを宣言するには次の 3 つの項目を指定します。

プロパティの名前

プロパティの型

プロパティの値を読み書きするメソッド。write メソッドが宣言されなければ，プロパティは読み出し専用

コンポーネントのクラス宣言の published セクションでに宣言したプロパティは，設計時にオブジェクトインスペクタで編集できます。public セクションで宣言したプロパティは実行時に使用可能で，プログラムコードで読み出したり設定したりできます。


An example of a property declaration
An example of a property declaration1115008

Section topics

Count プロパティの代表的な宣言の例を次に示します。

type

TYourComponent = class(TComponent)

private

FCount: Integer;	{内部記憶用}

procedure SetCount (Value: Integer);	{書き込みメソッド}

public

property Count: Integer read FCountwrite SetCount;

end;


Internal data storage (properties)
Internal data storage1115009

Section topics	参照

プロパティのデータを格納する方法には，なんの制約もありません。ただし一般的には，Delphi コンポーネントには次の規則があります。

プロパティのデータはクラスフィールドに格納される

プロパティデータの格納に使うフィールドはプライベートなので，コンポーネント自身の中からのみアクセスする。派生コンポーネントは継承プロパティを使わなければならず，プロパティの内部的なデータ記憶域に直接アクセスする必要はない

クラスフィールドの識別子はプロパティの名前の先頭に文字 F を加えたものとする。たとえば，TControl で定義された Width プロパティは，FWidth というフィールドに格納される

以上の背景となる基本原則は，プロパティの実装メソッドだけがプロパティの背後にあるデータにアクセスする，ということです。このため，メソッドやほかのプロパティがそのようなデータを操作する場合は，記憶域のデータに直接アクセスするのではなく，プロパティをとおして操作を行います。そうすれば，継承したプロパティの実装方法を変更しても，派生したコンポーネントが無効になるようなことはありません。


Direct access
Direct access1115010

Section topics	参照	例

プロパティデータを処理する最も簡単な方法は，データに直接アクセスすることです。それには，プロパティ宣言の read 部と write 部で，プロパティ値の代入と読み出しは，アクセスメソッドの呼び出しではなく，内部的な記憶フィールドへの直接アクセスで行う，ということを指定します。プロパティをオブジェクトインスペクタで操作したいが，プロパティ値の変更で即時処理が行われない場合には，直接アクセスは便利です。

一般によく行われる方法では，プロパティ宣言の read 部では直接アクセスを指定し， write 部ではメソッドの使用を指定します。書き込みではメソッドを使用するので，プロパティ値を変更するとコンポーネントの状態が更新されます。


An example of a property that uses direct access
An example of a property that uses direct access1115011

Section topics

次の例では，コンポーネント型宣言の read 部と write 部の両方でプロパティに直接アクセスを指定しています。

type

TSampleComponent = class(TComponent)

private	{内部記憶はプライベート}

FMyProperty: Boolean;	{プロパティ値を入れておくフィールドを宣言}

published	{設計時にプロパティを操作可能にする}

property MyProperty: Boolean read FMyProperty write FMyProperty;

end;


Access methods (properties)
Access methods1115012

Section topics	例

プロパティ宣言の read 部と write 部には，フィールドのかわりにアクセスメソッドを指定できます。アクセスメソッドはプロテクトにしなければならず，通常は virtual と宣言します。これにより，下位コンポーネントはプロパティの実装をオーバーライドできます。

アクセスメソッドをパブリックにしないでください。アクセスメソッドをプロテクトに保てば，アプリケーション開発者がアクセスメソッドのいずれかを呼び出し，プロパティを誤って変更してしまうことはありません。

The read method1115013

プロパティの read メソッドは，パラメータを 1 つも取らない（後述する例外を除く）関数で，そのプロパティと同じ型の値を返します。命名規則によって，この関数の名前はプロパティ名の先頭に「Get」を加えた名前にします。たとえば，Count という名前のプロパティの read メソッドは GetCount となります。read メソッドは内部記憶データに対して必要な処理を行って，適切な型のプロパティ値を生成します。

パラメータを取らないという規則の唯一の例外は配列プロパティとインデックス指定子を使うプロパティの場合で，どちらもインデックス値をパラメータとして渡します。インデックス指定子は，いくつかのプロパティで共有する単一の read メソッドを作成するために使います。インデックス指定子についての詳細は，『Object Pascal 言語リファレンス』を参照してください。

read メソッドを宣言しなければ，そのプロパティは書き込み専用になります。書き込み専用プロパティが使用されることはほとんどありません。

The write method1115014

プロパティの write メソッドは，そのプロパティと同じ型の 1 つのパラメータを取る（後述する例外を除く）手続きです。このパラメータは，参照渡しと値渡しのいずれの方法でも受け取ることができ，またどのような名前でも付けられます。命名規則によって，write メソッドの名前はプロパティ名の先頭に「Set」を加えた名前にします。たとえば，Count という名前のプロパティの write メソッドは SetCount となります。パラメータに渡された値は，そのプロパティの新しい値になります。write メソッドは，データを適切にプロパティの内部記憶に格納するために必要なすべての処理を行います。

1 つのパラメータを取るという規則の唯一の例外は配列プロパティとインデックス指定子を使うプロパティの場合で，どちらもインデックス値をもう 1 つのパラメータとして渡します。インデックス指定子は，いくつかのプロパティで共有する単一の write メソッドを作成するために使います。インデックス指定子についての詳細は，『Object Pascal 言語リファレンス』を参照してください。

write メソッドを宣言しなければ，そのプロパティは読み出し専用になります。

write メソッドでは，プロパティの変更の前に，新しく設定する値が現在値と異なっているかどうかを検査することがよくあります。次の例では，整数プロパティ Count の write メソッドがフィールド FCount に値を格納しています。

procedure TMyComponent.SetCount(Value: Integer);

begin

if Value <> FCount then

begin

FCount := Value;

Update;

end;

end;


Default property values
Default property values1115015

Section topics	参照	例

プロパティを宣言する場合， そのプロパティのデフォルト値を宣言できます。また，デフォルト値によって，プロパティをフォームファイルに保存するかどうかが決定されます。プロパティの保存とデフォルト値の関係については，26-4 ページの「プロパティの保存と読み込み」を参照してください。プロパティにデフォルト値を指定しなかった場合には，そのプロパティは常に保存されます。

プロパティのデフォルト値を指定するには，プロパティの宣言（または再宣言）に default 指令を追加して，その後にデフォルト値を記述します。たとえば次のようにします。

property Cool Boolean read GetCool write SetCool default True;

メモ	デフォルト値を宣言しても，プロパティがその値に設定されるわけではありません。コンポーネントのコンストラクタメソッドは，適切なときにプロパティ値を初期化しなければなりません。しかし，オブジェクトは常に自分のフィールドを 0 に初期化するので，コンストラクタは必ずしも整数プロパティを 0 に，文字列プロパティをヌルに，論理型プロパティを False に設定する必要はありません。

Specifying no default value1115016

プロパティを再宣言する場合は，継承したプロパティがデフォルト値を持っていたときでも，そのプロパティがデフォルト値を持たないように指定できます。

プロパティがデフォルト値を持たないように指定するには，そのプロパティの宣言に nodefault 指令を追加します。たとえば次のようにします。

property FavoriteFlavor string nodefault;

あるプロパティを初めて宣言する場合は nodefault を指定する必要はありません。デフォルト値を宣言しなければ，デフォルト値はないことになります。


An example of a property with a default value
An example of a property with a default value1115017

Section topics

コンポーネント宣言の次の例は，デフォルト値 True を持つ論理型プロパティ IsTrue を示しています。ユニットの implementation セクション内の宣言の下に，プロパティを初期化するコンストラクタがあります。

type

TSampleComponent = class(TComponent)

private

FIsTrue: Boolean;

public

constructor Create(AOwner: TComponent); override;

published

property IsTrue: Boolean read FIsTrue write FIsTrue default True;

end;

...

constructor TSampleComponent.Create(AOwner: TComponent);

begin

inherited Create(AOwner);	{継承したコンストラクタを呼び出す}

FIsTrue := True;	{デフォルト値を設定する}

end;


Creating array properties
Creating array properties1115018

Section topics	参照	例

プロパティの中には，配列と同様にインデックス付けされたプロパティがあります。たとえば，TMemo の Lines プロパティはメモのテキストを構成するインデックス付けされた文字列のリストで，文字列の配列として扱えます。この Lines によって，大きなデータ（メモテキスト）の中の特定の要素（文字列）に簡単にアクセスできます。

配列プロパティはほかのプロパティと同じように宣言できますが，以下の点が異なります。

宣言に，型を持つインデックスが 1 つまたは複数個含まれる。インデックッスには任意の型が指定できる

プロパティの宣言に read 部と write 部を記述する場合は，メソッドを指定しなければならない。フィールドは指定できない

配列プロパティの read メソッドと write メソッドは，インデックスを示すパラメータを追加的に受け取ります。このパラメータの順序は，宣言で指定されたインデックスと同じ順序，同じ型でなければなりません。

配列プロパティと配列にはいくつか相違点があります。配列プロパティのインデックスは，配列のインデックスと違って，整数型にする必要がありません。たとえば，プロパティを文字列によってインデックス付けをすることができます。また，配列プロパティでは個々の要素が参照できるだけで，プロパティの全範囲は参照できません。


An example of an array property
An example of an array property1115019

Section topics

次の例では，整数インデックスによって文字列を返すプロパティの宣言を示します。

type

TDemoComponent = class(TComponent)

private

function GetNumberName(Index: Integer): string;

public

property NumberName[Index: Integer]: string read GetNumberName;

end;

...

function TDemoComponent.GetNumberName(Index: Integer): string;

begin

Result := 'Unknown';

case Index of

-MaxInt..-1: Result := 'Negative';

0: Result := 'Zero';

1..100: Result := 'Small';

101..MaxInt: Result := 'Large';

end;

end;


Writing property editors
Writing property editors1115020

Section topics	参照

オブジェクトインスペクタでは，配列を除くすべてのプロパティ用にデフォルトの編集機能が用意されています。ただし配列プロパティ用のエディタだけでなく，ほかのプロパティ用の代替エディタも作成できます。カスタムエディタは，開発したコンポーネントのプロパティだけに適用するように登録することも，指定した型のプロパティすべてに適用するように登録することもできます。

プロパティエディタは次の 2 つの方法で使用されます。つまり，現在値をテキスト文字列として表示してユーザーに編集させる方法と，いくつもの編集機能を備えたダイアログボックスを表示する方法の 2 つです。開発者は，編集するプロパティにとってどの方法が便利であるか判断して，どちらの方法を使用するか決定します。

プロパティエディタの開発は以下の 5 つのことを行います。

プロパティエディタオブジェクトを派生させる

プロパティをテキストとして編集する

プロパティを全体として編集する

エディタ属性を指定する

プロパティエディタを登録する


Deriving a property-editor class
Deriving a property-editor class1115021

Section topics	参照	例

プロパティエディタを作成するには，既存のプロパティエディタ型の 1 つから新しいクラスを派生させます。DSGNINTF ファイルには数種類のプロパティエディタが定義されていますが，これらのエディタはすべて，TPropertyEditor を継承しています。TPropertyEditor から直接プロパティエディタクラスを派生させる方法と，表に示すプロパティエディタ型の 1 つから派生させる方法があります。

型	編集できるプロパティ
TOrdinalProperty	すべての順序型（整数型，文字型，列挙型）のプロパティのためのプロパティエディタは，TOrdinalProperty を継承する
TIntegerProperty	すべての整数型。定義済みの部分範囲型とユーザー定義の部分範囲型を含む
TCharProperty	Char 型と，Char の部分範囲型（'A'..'Z' など）
TEnumProperty	すべての列挙型
TFloatProperty	すべての浮動小数点数
TStringProperty	文字列。string [20] のような特定の長さの文字列を含む
TSetElementProperty	集合の個々の要素。論理値として表示される
TSetProperty	すべての集合。集合は直接には編集できないが，集合要素プロパティのリストに展開できる
TClassProperty	オブジェクト。オブジェクト型の名前を表示し，そのオブジェクトのプロパティを展開できる
TMethodProperty	メソッドポインタ。特に，イベントを扱う
TComponentProperty	同じフォーム上のコンポーネント。ユーザーはコンポーネントのプロパティを編集できないが，互換のある型の特定のコンポーネントを指示できる
TCaptionProperty	キャプションとテキスト用のエディタ。プロパティが変更されるたびに実際のプロパティの値を更新する
TComponentNameProperty	コンポーネント名。複数のコンポーネントが選択されているときに，表示される名前プロパティを制限する
TCursorProperty	カーソル。該当する場合は clXXX 値でその色を表示し，該当しない場合は 16 進値で表示する。リストから clXXX 値を選択することもできる
TShortCutProperty	キーボードショートカット。ショートカット値を入力するか，リストからショートカット値を選択できる
TMPFilenameProperty	メディアファイルの名前。メディアファイルの名前を含む［ファイルを開く］ダイアログボックスを表示する
TTabOrderProperty	タブ順。複数のコンポーネントが選択されているときに表示されるコンポーネントの表示を制限する
TColorProperty	コンポーネントの色。色定数に該当すればそれを表示し，そうでない場合は 16 進数で表示する。ドロップダウンリストには色定数が入っている。ダブルクリックすると色選択ダイアログボックスが開く
TFontNameProperty	フォント名。ドロップダウンリストには現在インストールされているすべてのフォントが表示される
TFontProperty	フォント。フォントダイアログボックスにアクセスでき，また，個々のフォントプロパティを展開できる
メモ	DsgnIntf ユニットでは，Name などの特殊なプロパティに対して使用するいくつかの特殊なエディタも定義されています。ここに示したのは，コンポーネント開発者にとって特に有用と思われるプロパティエディタです。


An example of a property-editor class
An example of a property-editor class1115022

Section topics

最も単純なプロパティエディタの 1 つは，浮動小数点数のプロパティ用の TFloatProperty です。その宣言の例を次に示します。

type

TFloatProperty = class(TPropertyEditor)

public

function AllEqual: Boolean; override;

function GetValue: string; override;

procedure SetValue(const Value: string); override;

end;


Editing the property as text
Editing the property as text1115023

Section topics

すべてのプロパティには，オブジェクトインスペクタで表示するために，値の文字列表現を用意しなければなりません。また，ほとんどのプロパティでは，開発者は設計時に新しい値を入力できます。プロパティエディタクラスの仮想メソッドをオーバーライドすることで，文字列表現と実際の値とを変換します。

オーバーライドするメソッドの名前は，GetValue と SetValue です。プロパティエディタはまた，次の表で示すように，さまざまな型の値の代入と読み出しに使用されるメソッド群を継承します。

プロパティの型	「Get」メソッド	「Set」メソッド
浮動小数点数	GetFloatValue	SetFloatValue
メソッドポインタ（イベント）	GetMethodValue	SetMethodValue
順序型	GetOrdValue	SetOrdValue
文字列	GetStrValue	SetStrValue
通常，GetValue メソッドをオーバーライドする新しいメソッドも，「Get」メソッドの 1 つを呼び出します。SetValue メソッドをオーバーライドするメソッドは，「Set」メソッドの 1 つを呼び出します。

Displaying the property value1115024

GetValue メソッドは，そのプロパティの現在値を表す文字列を返します。オブジェクトインスペクタは，この文字列をそのプロパティの値列に表示します。デフォルトでは，GetValue は '(Unknown)' を返します。独自のプロパティの文字列表現を用意するには，プロパティエディタの GetValue メソッドをオーバーライドします。プロパティが文字列を持たない場合は，GetValue はその値を文字列に変換しなければなりません。

Setting the property value1115025

プロパティエディタの SetValue メソッドは，オブジェクトインスペクタで入力した文字列を受け取り，その文字列を適切な型に変換し，プロパティの値を設定します。文字列値をプロパティに設定するには，プロパティエディタの SetValue メソッドをオーバーライドします。SetValue は文字列を値に変換し，検証してから「Set」メソッドの 1 つを呼び出します。受け取った文字列がプロパティの適正な値を表していなかった場合，SetValue は例外を生成します。

TIntegerProperty の GetValue メソッドと SetValue メソッドの例を次に示します。Integer は順序型なので，GetValue は GetOrdValue を呼び出して，値を文字列に変換します。SetValue はこの文字列を整数に変換し，値の範囲を検査してから SetOrdValue を呼び出します。

function TIntegerProperty.GetValue: string;

begin

Result := IntToStr(GetOrdValue);

end;

procedure TIntegerProperty.SetValue(const Value: string);

var

L: Longint;

begin

L := StrToInt(Value);	{文字列を数値に変換}

with GetTypeData(GetPropType)^ do	{ここで Integer 型のコンパイラデータが使用される}

if (L < MinValue) or (L > MaxValue) then	{範囲内にあることを確認 ...}

raise EPropertyError.Create(	{...範囲内にない場合は例外を生成}

FmtLoadStr(SOutOfRange, [MinValue, MaxValue]));

SetOrdValue(L);	{範囲内にあれば処理を続行して値を設定}

end;


Editing the property as a whole
Editing the property as a whole1115026

Section topics

オブジェクトインスペクタでのテキスト編集機能のかわりに（またはそれに加えて），プロパティを設定するダイアログボックスを用意できます。プロパティエディタが最もよく使用されるのは，それ自身がクラスであるプロパティに対してです。そのよい例が Font プロパティです。このプロパティに関連したエディタダイアログボックスを使って，開発者は特定のフォントのすべての属性を一度に指定することができます。

ユーザーがプロパティの隣の［...］ボタン（省略ボタン）をクリックするか，プロパティ値をダブルクリックすると，オブジェクトインスペクタがプロパティエディタの Edit メソッドを呼び出します。エディタダイアログボックスを用意するには，プロパティエディタクラスの Edit メソッドをオーバーライドします。Edit メソッドは，GetValue メソッドと SetValue メソッドで使ったのと同じ「Get」メソッドと「Set」メソッドを使います。Edit メソッドは「Get」メソッドと「Set」メソッドの両方を呼び出します。このエディタは特定の型を扱うので，通常はプロパティ値を文字列に変換する必要はありません。

Edit メソッドの実装内で，次の手順を実行します。

1.	プロパティ用のエディタを作成します。

2.	「Get」メソッドを使って現在値を読み出し，プロパティに代入します。

3.	ユーザーが新しい値を選択した場合は，「Set」メソッドを使ってその値をプロパティに代入します。

4.	エディタを廃棄します。

ほとんどのコンポーネントが持つ Color プロパティは，Windows の［色の設定］コモンダイアログボックスをプロパティエディタとして使用します。TColorProperty の Edit メソッドの例を次に示します。このメソッドは［色の設定］ダイアログボックスを呼び出して，その結果を使用します。

procedure TColorProperty.Edit;

var

ColorDialog: TColorDialog;

begin

ColorDialog := TColorDialog.Create(Application); {エディタを構築}

try

ColorDialog.Color := GetOrdValue; {既存の値を使用}

if ColorDialog.Execute then{ユーザーがそのダイアログボックスで OK を選択した場合は ...}

SetOrdValue(ColorDialog.Color); {...その結果を使用して値を設定}

finally

ColorDialog.Free; {エディタを廃棄}

end;

end;


Specifying editor attributes
Specifying editor attributes1115027

Section topics	参照	例

オブジェクトインスペクタが適切なツールを表示できるように，プロパティエディタはいくつかの情報を通知しなければなりません。たとえば，プロパティにサブプロパティがあるのかどうか，可能な値のリストを表示できるのかどうか，などです。

エディタ属性を指定するには，プロパティエディタの GetAttributes メソッドをオーバーライドします。GetAttributes は TPropertyAttributes 型の値の集合を返します。

フラグ	関連メソッド	含まれている場合の意味
paValueList	GetValues	このエディタは列挙値のリストを与えることができる
paSubProperties	GetProperties	このプロパティには表示できるサブプロパティがある
paDialog	Edit	このエディタはプロパティを全体として編集するためのダイアログボックスを表示できる
paMultiSelect	なし	このプロパティは，ユーザーが 2 つ以上のコンポーネントを選択したときのみ表示する
paAutoUpdate	SetValue	値が確定する前でも，変更が行われるたびにコンポーネントを更新する
paSortList	なし	オブジェクトインスペクタがその値リストを並べ替えられる
paReadOnly	なし	ユーザーはそのプロパティ値を変更できない
paRevertable	なし	オブジェクトインスペクタのコンテキストメニュー項目［継承元の値に戻す(R)］を使用可能にする。このメニュー項目を選択すると，プロパティエディタは現在のプロパティ値を破棄して，以前に確立されたデフォルト値または標準値の設定に戻す


An example of specifying editor attributes
An example of specifying editor attributes1115028

Section topics

Color プロパティは，ほかのプロパティと比べてかなり柔軟です。ユーザーはオブジェクトインスペクタで，入力，リストからの選択，カスタマイズされたエディタによる指定など，いくつかの方法によってこのプロパティを変更できます。このため，TColorProperty の GetAttributes メソッドの戻り値には，次のようにいくつかの属性が入っています。

function TColorProperty.GetAttributes: TPropertyAttributes;

begin

Result := [paMultiSelect, paDialog, paValueList];

end;


Registering the property editor
Registering the property editor1115029

Section topics	参照	例

プロパティエディタを作成したら，次にそれを Delphi に登録します。プロパティエディタを登録すると，指定したプロパティの型とプロパティエディタとが関連付けられます。エディタの登録では，特定の型を持つすべてのプロパティを指定することも，特定の型の特定のプロパティだけを指定することもできます。

プロパティエディタを登録するには，手続き RegisterPropertyEditor を呼び出します。RegisterPropertyEditor は次の 4 つのパラメータを受け取ります。

編集するプロパティの型を示す型情報ポインタ
これは常に，TypeInfo (TMyComponent) など，TypeInfo 組み込み関数に対する呼び出しにします。

エディタが適用されるコンポーネントのクラス
このパラメータが nil の場合には，このエディタはすべてのコンポーネントクラスで指定の型のプロパティすべてに適用されます。

プロパティの名前
このパラメータは，直前のパラメータによって特定のクラスのコンポーネントが指定された場合にのみ有効です。この場合には，このエディタが適用されるコンポーネントクラスのプロパティを指定できます。

指定のプロパティの編集に使用されるプロパティエディタの型


An example of registering a property editor
An example of registering a property editor1115030

Section topics

コンポーネントパレットの標準コンポーネント用のエディタを登録する手続きの一部を例として次に示します。

procedure Register;

begin

RegisterPropertyEditor(TypeInfo(TComponent), nil, '', TComponentProperty);

RegisterPropertyEditor(TypeInfo(TComponentName), TComponent, 'Name',	 TComponentNameProperty);

RegisterPropertyEditor(TypeInfo(TMenuItem), TMenu, '', TMenuItemProperty);

end;

この手続きの 3 つの文は，次のような 3 通りの RegisterPropertyEditor の使用方法を記述しています。

最初の文は，最も一般的な登録を行っています。この文では，TComponent 型と，登録済みの独自のエディタを持たない TComponent の下位オブジェクト型のプロパティすべてに対して，プロパティエディタ TComponentProperty が登録されています。通常， ある特定の型のためのプロパティエディタを作成し，そのエディタをその型のすべてのプロパティに対して指定します。このため，2 番目と 3 番目のパラメータがそれぞれ nil と空文字列になっています。

2 番目の文は，指定の型のコンポーネントの指定のプロパティ用にエディタを登録しています。この例では，すべての該当するコンポーネントの Name プロパティ用にエディタを登録しています。

3 番目の文には，1 番目の文よりは限定的で，2 番目の文よりは一般的な登録を行っています。この文では，TMenu 型のコンポーネントの TMenuItem 型のすべてのプロパティ用にエディタを登録しています。


Creating events
Creating events1104001

Section topics	参照

イベントとは，ユーザーアクションやフォーカスの変更などのシステムの出来事と，その出来事に応答するコードとの間の関連付けのことです。この応答コードがイベントハンドラで，ほとんどの場合アプリケーション開発者によって記述されます。アプリケーション開発者は，イベントを使ってクラスそのものを変更することなくコンポーネントの動作をカスタマイズできます。

マウスアクションなど，よく発生するユーザーアクションに対するイベントは，すべての標準コンポーネントに組み込まれています。しかし，独自のイベントも作成できます。この章では，コンポーネントのイベントの作成について以下のことを説明します。

イベントとはなにか

標準イベントの実現

独自のイベントの定義

イベントはプロパティとして実現されます。このため，コンポーネントのイベントを作成／変更するには，「プロパティの作成」をまず読んでください。


What are events?
What are events?1104002

Section topics	参照

イベントとは，ある出来事とコードを関連付けるメカニズムのことです。より具体的には，イベントはメソッドポインタです。つまり，特定のクラスインスタンスのメソッドを指すポインタです。

アプリケーション開発者にとってのイベントは，システムの出来事に関連付けられた OnClick などの名前で示され，特定のコードを結び付けられます。たとえば，Button1 という名前の押しボタンは，OnClick メソッドを伴っています。デフォルトでは Delphi は，このボタンのあるフォームに Button1Click という名前のイベントハンドラを生成し，OnClick に関連付けます。このボタンでクリックイベントが発生すると，ボタンは OnClick のメソッド，つまりこの場合は Button1Click を呼び出します。イベントを記述するために，以下のことについて説明します。

イベントはメソッドポインタである

イベントはプロパティである

イベントの型はメソッドポインタ型である

イベントハンドラはオプションである


Events are method pointers
Events are method pointers1104003

Section topics

イベントはメソッドポインタとして実現されます。メソッドポインタは，インスタンスオブジェクトの特定のメソッドを指すポインタ型です。コンポーネント開発者はメソッドポインタをプレースホルダとして扱えます。つまり，コンポーネントのコードがイベントを検出した場合，ユーザーがそのイベントに対して指定しているメソッドがあれば，そのメソッドを呼び出します。

メソッドポインタはほかの手続き型と同じように動作しますが，手続き型と違ってオブジェクトへの隠されたポインタを保持しています。アプリケーション開発者がコンポーネントのイベントにハンドラを指定した場合，この指定は特定のインスタンスオブジェクトのメソッドに対する指定であって，単に特定の名前のメソッドに対して指定したわけではありません。このオブジェクトは通常，そのコンポーネントが所属するフォームですが，そうでない場合もあります。


Events are properties
Events are properties1104004

Section topics

コンポーネントはプロパティによってイベントを実現します。ほかのプロパティとは異なり，イベントはメソッドを使用して read 部と write 部を実現するわけではありません。そのかわりに，イベントプロパティは同じ型のプライベートなクラスフィールドをプロパティとして使用します。

このフィールドの名前は，通常，プロパティの名前の先頭に文字 F を加えた名前とします。たとえば，OnClick メソッドのポインタは TNotifyEvent 型の FOnClick という名前のフィールドに格納されます。OnClick イベントプロパティの宣言を次に示します。

type

TControl = class(TComponent)

private

FOnClick: TNotifyEvent;	{ メソッドポインタを収容するフィールドを宣言 }

...

protected

property OnClick: TNotifyEvent read FOnClick write FOnClick;

end;

ほかのプロパティの場合と同じように，イベントの値は実行時に設定または変更できます。ただし，イベントをプロパティとする主要な利点は，コンポーネントユーザーが設計時にオブジェクトインスペクタでイベントにハンドラを指定できることです。


Event types are method-pointer types
Event types are method-pointer types1104005

Section topics

イベントはイベントハンドラに対するポインタなので，イベントプロパティの型はメソッドポインタ型でなければなりません。同様に，イベントハンドラとして使用されるすべてのコードは，適切な型を持つオブジェクトメソッドでなければなりません。

イベントハンドラはすべて手続きです。互換性のため，定義するイベントハンドラはデフォルトのイベントハンドラと同じ数，同じ型のパラメータを，同じ順序，同じ方法で受け取らなければなりません。

Delphi はすべての標準イベントに対してメソッド型を定義しています。独自のイベントを作成する場合は，既存の型が適切ならばそれを使用できます。そうでなければ独自の型を定義します。

Event-handler types are procedures1104006

関数のメソッドポインタ型を宣言してもコンパイラはエラーを発生しませんが，関数ではイベントを処理しないでください。関数が空の場合，返される結果は不定なので，空の関数であるようなイベントハンドラは有効とは限りません。そのため，すべてのイベントとイベントハンドラは手続きにします。

イベントハンドラを関数にすることはできませんが，var パラメータを使用すればアプリケーション開発者のコードから情報を取得できます。この場合は，必ずパラメータに有効な値を代入してからそのハンドラを呼び出すようにしてください。そうしないと，ユーザーが常に値を設定しなければなりません。

TKeyPressEvent 型の OnKeyPress イベントでは，var パラメータを使用します。次のように TKeyPressEvent では，どのオブジェクトがそのイベントを生成したかを示すパラメータと，どのキーが押されたかを示すパラメータの 2 つが定義されています。

type

TKeyPressEvent = procedure(Sender: TObject; var Key: Char) of object;

通常，Key パラメータはユーザーが押した文字を示します。ただし，場合によってはコンポーネントユーザーがその文字を変更することがあります。たとえば，エディタの入力ですべての文字を大文字に変換する場合です。それには，次のようなキー入力用のハンドラを定義できます。

procedure TForm1.Edit1KeyPressed(Sender: TObject; var Key: Char);

begin

Key := UpCase(Key);

end;

また，var パラメータによってユーザーがデフォルトの処理をオーバーライドできるように設計することも可能です。


Event handlers are optional
Event handlers are optional1104007

Section topics

イベントを作成する場合は，コンポーネントを使う開発者がイベントにハンドラを結び付けないことがあるので注意してください。つまり，特定のイベントにハンドラが結び付けられていなくても，それだけでコンポーネントが障害を起こしたりエラーを出したりしないようにします。ハンドラの呼び出しと，ハンドラが結び付けられていないイベントの処理のメカニズムについては，「イベントの呼び出し.」で説明します。

Windows アプリケーションでは常にイベントが発生しています。ビジュアルコンポーネントを横切ってマウスポインタを移動させるだけで，Windows は無数のマウス移動メッセージを送り出し，コンポーネントはそのメッセージを OnMouseMove イベントに変換します。しかし多くの場合，開発者はマウス移動イベントを処理したくはなく，それで問題が生じてはなりません。したがって，作成するコンポーネントでは，イベント用のハンドラが必要です。

さらに，アプリケーション開発者がイベントハンドラに記述できるコードに制約はありません。VCL のコンポーネントのイベントハンドラは，エラーが発生するような事態がなるべく起きないように記述されています。確かに，アプリケーションコードの論理エラーは回避できません。しかし，イベントが呼び出される前にデータ構造が初期化されるように記述し，アプリケーション開発者が無効なデータを参照しないように配慮することは可能です。


Implementing the standard events
Implementing the standard events1104008

Section topics	参照

Delphi のコントロールは，Windows でよく起こる出来事に対するイベントを継承しています。そのようなイベントを標準イベントと呼びます。標準イベントのすべてはコントロールに組み込まれていますが，標準イベントは「通常」protected になっているので，開発者は標準イベントにハンドラを結び付けられません。しかしコントロールを作成する場合は，そのコントロールのユーザーがアクセスできるようにすることは可能です。

標準イベントをコントロールで処理する場合は次の 3 点について考慮します。

標準イベントとは

イベントを公開する方法

標準イベントの処理方法の変更


Identifying standard events
Identifying standard events1104009

Section topics	参照

標準イベントには，すべてのコントロールに対して定義されているイベントと，標準ウィンドウコントロールに対してのみ定義されているイベントの 2 種類があります。

Standard events for all controls1104010

最も基本的なイベントは，TControl クラスで定義されています。ウィンドウ，グラフィック，カスタムのどの種類のコントロールも，そのイベントを継承します。以下に，すべてのコントロールで処理できるイベントを示します。

OnClick	OnDragDrop	OnEndDrag	OnMouseMove
OnDblClick	OnDragOver	OnMouseDown	OnMouseUp

標準イベントに対応する仮想プロテクトメソッドが TControl に宣言されており，各仮想メソッド名はイベント名に対応しています。たとえば，OnClick イベントは Click というメソッドを呼び出し，OnEndDrag イベントは DoEndDrag というメソッドを呼び出します。

Standard events for standard controls1104011

標準ウィンドウコントロールは，すべてのコントロールに共通のイベントに加えて，以下に示すイベントを処理できます。標準ウィンドウコントロールは TWinControl から派生したものです。

OnEnter	OnKeyDown	OnKeyPress
OnKeyUp	OnExit

TControl の標準コントロールと同様に，ウィンドウコントロールイベントにも対応するメソッドがあります。


Making events visible
Making events visible1104012

Section topics	参照	例

TControl と TWinControl での標準イベントの宣言は，それに対応するメソッドと同様に protected になっています。これらの抽象クラスから継承していて実行時または設計時に標準イベントにアクセスできるようにするには，そのイベントを public または published として再宣言します。

プロパティを実現方法の指定なしで再宣言すると，メソッドの保護レベル（アクセス制御）だけが変更されます。この方法で，TControl で定義されているが表示されないイベントを public または published として宣言し，アクセスできるようにします。


An example of making an event visbile
An example of making an event visbile1104013

Section topics

コンポーネントの OnClick イベントを設計時にアクセスできるようにするには，コンポーネントのクラス宣言に次のコードを記述します。

type

TMyControl = class(TCustomControl)

...

published

property OnClick;

end;


Changing the standard event handling
Changing the standard event handling1104014

Section topics	参照	例

コンポーネントが一定の種類のイベントに応答する方法を変更する場合は，コードを記述してそのイベントに割り当てたいでしょう。それこそがアプリケーション開発者の仕事です。しかし，コンポーネントの作成中は，そのコンポーネントを使う開発者がそのイベントを使えるようにしておかなければなりません。

標準イベントのそれぞれが protected として宣言されたメソッドで実現されているのはこのためです。このメソッドをオーバーライドすれば，内部のイベント処理方法を変更できます。そこで継承したメソッドを呼び出せば，元の標準イベント処理やアプリケーション開発者のコードで記述された処理を実行できます。

メソッドを呼び出す順序が重要です。一般には，継承したメソッドを最初に呼び出して，カスタマイズの前にアプリケーション開発者のイベントハンドラを実行します。継承したメソッドの実行結果によっては，カスタマイズ処理を実行しないこともできます。ただし，継承したメソッドを呼び出す前にカスタマイズ処理を実行したい場合もあります。たとえば，継承したコードがコンポーネントの状態に依存している場合に，カスタマイズしたコードで状態をあらかじめ変更しておくことがあります。このような場合は，状態を変更した後にユーザーコードを実行して，ユーザーコードが変更済みの状態を参照できるようにします。


An example of changing the standard event handling
An example of changing the standard event handling1104015

Section topics

開発中のコンポーネントで，クリックに応答する方法を変更するとします。アプリケーション開発者と同じ方法で OnClick イベントにハンドラを結び付けるかわりに，次のように Click プロテクトメソッドをオーバーライドします。

procedure click override { forward declaration }

...

procedure TMyControl.Click;

begin

inherited Click;	{ハンドラの呼び出しなど標準的な処理を実行}

{ここにコンポーネント開発者のカスタマイズコードを記述}

end;


Defining your own events
Defining your own events1104016

Section topics	参照

まったく新しいイベントを定義することは，それほど多くはありません。しかし，あるコンポーネントにほかのコンポーネントとはまったく異なる動作を与える場合もあり，その場合にはコンポーネントのイベントを新しく定義します。

イベントを定義するときに考慮すべき事項は以下のとおりです。

イベントの発生

ハンドラ型の定義

イベントの宣言

イベントの呼び出し


Triggering the event
Triggering the event1104017

Section topics	参照

まず，何がイベントを発生させるのかという問題があります。イベントによっては答えは明白です。たとえば，マウスボタンが押されたことを示すイベントは，ユーザーがマウスの左ボタンを押して，Windows がアプリケーションに WM_LBUTTONDOWN メッセージを送ったときに発生します。コンポーネントはこのメッセージを受け取ると MouseDown メソッドを呼び出します。MouseDown メソッドは，ユーザーが OnMouseDown イベントに結び付けたコードを呼び出します。

しかし，それほど明確に外部の出来事と結び付いていないイベントもあります。たとえば，スクロールバーの OnChange イベントは，キー入力，マウスクリック，またはほかのコントロールの変更などさまざまな出来事によって発生します。イベントを定義する際には，それぞれの出来事が適切なイベントを呼び出すように配慮します。

Two kinds of event1104018

ユーザーの操作と状態の変更という 2 種類の出来事に対してイベントを用意します。ユーザー操作によるイベントは，Windows からのメッセージによって発生します。このイベントは多くの場合，コンポーネントが応答しなければならないようなユーザー操作が行われたことを示します。これに対して，状態の変更によるイベントは，フォーカスの変更のような Windows からのメッセージによっても発生しますが，プロパティやコードによる変更によっても発生します。どのようなイベントを定義するかは，全面的に開発者にまかされています。開発者がイベントの使用方法をよく理解できるようにイベントを定義してください。


Defining the handler type
Defining the handler type1104019

Section topics	参照

イベントの発生方法について決定したら，次にそのイベントの処理方法を定義します。つまり，イベントの型を決定します。多くの場合，開発者が定義したイベントのハンドラは，簡単な通知を行うものかイベント独自の型を持つものです。また，ハンドラから情報を取得することもできます。

Simple notifications1104020

通知イベントとは，特定のイベントが発生したことを告げるだけのイベントで，発生した時期や場所についての具体的な情報は伴いません。通知イベントには TNotifyEvent 型を使用します。TNotifyEvent は，唯一のパラメータとしてイベントの発生元を持つだけです。このため，通知イベントのハンドラがそのイベントから得られる情報は，発生したイベントの種類と，そのイベントはどのコンポーネントで発生したのかということだけです。たとえば，クリックイベントは通知イベントです。クリックイベントのハンドラで利用できる情報は，クリックが発生したということと，どのコンポーネントがクリックされたかということだけです。

通知は一方通行です。たとえば，フィードバックを提供したり，通知イベントのそれ以上の処理を防止させるようなメカニズムは備えていません。

Event-specific handlers1104021

場合によっては，どのイベントがどのコンポーネントに対して発生したかという情報だけでは十分ではないことがあります。たとえば，キーが押されたことを示すイベントの場合，おそらくハンドラはユーザーがどのキーを押したのか知りたいはずです。このような場合には，必要な情報をパラメータとして含むハンドラが必要です。

メッセージによってイベントが発生した場合には，多くの場合メッセージのパラメータがそのままイベントのハンドラに渡されます。

Returning information from the handler1104022

すべてのイベントハンドラは手続きなので，ハンドラから情報を返す場合は var パラメータを使用します。ユーザーのハンドラを実行した後，返された情報によって，イベントを処理する方法やイベントを処理するかどうかを決定できます。

たとえば，すべてのキーイベント（OnKeyDown，OnKeyUp，OnKeyPress）は，Key パラメータにキーを示す値を参照渡しします。イベントハンドラで Key を変更すると，アプリケーションはその変更された値を受け取ります。このような方法で，たとえば入力された文字を大文字に変換できます。


Declaring the event
Declaring the event1104023

Section topics	参照

イベントハンドラの型を決定したら，次にそのイベントのメソッドポインタとプロパティを宣言します。ユーザーにわかりやすいように，イベントにはその機能を表すような説明的な名前を付けます。なるべく，同じようなイベントには一貫性のある名前を付けます。

Event names start with "On"1104024

Delphi の標準イベントの名前はほとんど「On」で始まりますが，これはコンパイラにとって必須ではありません。オブジェクトインスペクタは，プロパティの型によってそのプロパティがイベントかどうかを判断します。すべてのメソッドポインタプロパティはイベントとみなされ，［Events］ページに表示されます。

ただし，開発者はイベントに「On」で始まるアルファベットの名前が付いていることに慣れています。それ以外の名前を使用すると混乱する可能性があります。


Calling the event
Calling the event1104025

Section topics	参照

イベントの呼び出しはできるだけ集中させます。つまり，仮想メソッドを 1 つ作成して，アプリケーションのイベントハンドラが存在する場合はそれを呼び出し，必要なデフォルトの処理を行います。

イベントの呼び出しが 1 箇所で行われていれば，開発したコンポーネントから新しいコンポーネントを派生させる場合，イベントを呼び出す場所を探す負担が軽減されます。1 つのメソッドをオーバーライドすれば，イベントの処理をカスタマイズできるからです。

イベントを呼び出す場合は，次の2 つのことについても考慮します。

空のハンドラも有効であること

ユーザーがデフォルトの処理方法をオーバーライドできること


Empty handlers must be valid
Empty handlers must be valid1104026

Section topics	参照	例

空のイベントハンドラによってエラーが発生することのないようにしてください。また，コンポーネントの動作がアプリケーションのイベント処理コードからの特定の応答に依存しないようにしてください。


An example of calling an event handler
An example of calling an event handler1104027

Section topics

空のハンドラは，ハンドラがない場合と同じ結果をもたらすようにします。アプリケーションのイベントハンドラを呼び出すコードは，次のようになります。

if Assigned(OnClick) then OnClick(Self);

{ デフォルトの処理を実行 }

次のようなコードは記述しないでください。

if Assigned(OnClick) then OnClick(Self)

else { デフォルトの処理を実行 };


Users can override default handling
Users can override default handling1104028

Section topics	参照	例

ある種のイベントでは，開発者がデフォルトの処理方法を置き換えたり，すべての応答を抑止する場合があります。それを可能にするためには，ハンドラに引数を参照渡しして，ハンドラから返された値を検査します。

この方法は，空のハンドラはハンドラが存在しない場合と同じ結果をもたらすという規則と矛盾しません。空のハンドラでは参照渡しされる引数の値は変更されないので，空のハンドラが呼び出された後は，常にデフォルトの処理が行われます。


An example of overriding default handling
An example of overriding default handling1104029

Section topics

キーが押されたことを示すイベントの処理では，アプリケーション開発者は var パラメータ Key にヌル文字（#0）を設定することで，コンポーネントのデフォルトのキー入力処理を抑止できます。これを実現するコードは次のとおりです。

if Assigned(OnKeyPress) then OnKeyPress(Self, Key);

if Key <> #0 then	{デフォルトの処理を実行}

Windows メッセージを処理する必要があるため，実際のコードはこれとは少し異なりますが，基本的な論理は同じです。デフォルトでは，コンポーネントはユーザーのハンドラを（存在する場合は）呼び出してから，標準の処理を実行します。ユーザーのハンドラが Key にヌル文字を設定した場合には，コンポーネントはそのデフォルト処理を行いません。


Creating methods
Creating methods1107001

Section topics	参照

コンポーネントメソッドとは，クラスの構造に組み込まれた手続きや関数です。基本的には，コンポーネントメソッドで行えることには何の制約もありません。ただし，Delphi では標準的なメソッドを作成するための方法がいくつか定められています。この章では，以下のことを説明します。

相互依存を避ける

メソッドの命名

メソッドの保護の設定

仮想メソッドの作成

メソッドの宣言

一般に，コンポーネント内のメソッドの数も，アプリケーションで呼び出さなければならないメソッドの数もできるだけ少なくします。また，開発者がメソッドとして実現しようと考える機能の多くは，たいていの場合プロパティにカプセル化できます。プロパティを使用すれば Delphi 環境に適したインターフェースが作成され，設計時にプロパティを操作できます。


Avoiding dependencies
Avoiding dependencies1107002

Section topics	参照

コンポーネントを使用する際の前提条件が多くなると，開発者に負担がかかります。開発者がコンポーネントに対して，いつでもどのようなことでも行えるようにコンポーネントを設計します。この原則に従えない場合もありますが，できるだけこの原則に近づくことを目標とします。

以下に，避けた方がよい依存とはどのようなものかを示します。

ユーザーがコンポーネントを使用するときに必ず呼び出さなければならないメソッド

特定の順序で呼び出さなければならないメソッド

あるイベントやメソッドが無効になる状態やモードを招くメソッド

相互依存がある場合，不適切な状態から確実に抜け出せる方法を用意します。たとえば，あるメソッドの呼び出しがコンポーネントの状態を変化させ，その状態ではほかのメソッドの呼び出しが無効となるような場合には，状態を修正するための別のメソッドを用意しておきます。少なくとも，ユーザーが無効なメソッドを呼び出した場合に例外が生成されるようにしておきます。例外については『ユーザーズガイド』の第 7 章を参照してください。

つまり，コードの各部分が相互に依存する場合には，そのコードが間違った方法で使用されても，問題が生じないように配慮します。ユーザーがコンポーネントの依存関係に配慮しなかった場合でも，システム障害にするのではなく警告メッセージを表示するなどの方法を採ります。


Naming methods
Naming methods1107003

Section topics	参照

Delphi では，メソッドやパラメータに付ける名前に制約はありません。しかし，いくつかの命名規則に従えば，アプリケーション開発者にとってわかりやすいメソッドを作成できます。開発したコンポーネントが広く使用されるかどうかは，コンポーネントの設計にかかっています。

自分自身や小さなグループ内で使用するコードを開発する場合は，命名方法についてはそれほど考慮しないかもしれません。しかし，そのコードに不案内な，またはそもそもコーディング自体に不案内なユーザーによって使用されるコンポーネントを開発する場合は，メソッドに明確なわかりやすい名前を付けることが大切です。

メソッドにわかりやすい名前を付ける方法を以下に示します。

説明的な名前にする。意味を表す動詞を使う

PasteFromClipboard のような名前は，Paste や PFC のような短い名前よりもはるかにわかりやすい名前です。ReadFileNames も DoFiles よりわかりやすい名前です。

関数には返す値を表す名前を付ける

プログラマ本人にとっては，X という名前の関数が水平方向の位置を返すことは明白かもしれませんが，GetHorizontalPosition のような名前にすれば，すべてのユーザーが理解できます。

最後に，そのメソッドが本当に必要かどうか再考します。メソッド名に動詞が入っているかどうかで，その判断が可能です。名前に動詞が入っていないメソッドを数多く作成した場合は，そのメソッドをプロパティで実現できないかどうか考慮します。


Protecting methods
Protecting methods1107004

Section topics	参照

フィールド，メソッド，プロパティなどを含め，クラスの各部分には保護レベル，つまり「可視性」を設定できます。この点については，「アクセスの制御」で説明しました。あるメソッドに対して可視性を選択するのは容易です。

一般には，コンポーネントに記述するメソッドは public か protected のどちらかにします。メソッドを private にすることはほとんどありません。private にするのは，メソッドがそのコンポーネントに特有のもので，派生したコンポーネントからのアクセスさえ禁止するような場合です。


Methods that should be public
Methods that should be public1107005

Section topics	参照

アプリケーション開発者が呼び出すメソッドはすべて public として宣言します。メソッド呼び出しの多くはイベントハンドラで発生します。したがって，メソッドがシステムリソースを独占したり，Windows をユーザーに応答できないような状態にすることは適切ではありません。

メモ	コンストラクタとデストラクタは，常に public にします。


Methods that should be protected
Methods that should be protected1107006

Section topics	参照

コンポーネントの内部で使用するメソッドは，すべて protected にします。そうすれば，アプリケーションが誤ってそのメソッドを呼び出すことを防止できます。 protected として宣言したメソッドは，アプリケーションコードからは呼び出せませんが，下位クラスからは呼び出せます。

たとえば，一定のデータが設定されていることを前提とするメソッドがあるとします。メソッドをパブリックに設定した場合は，データが設定される前にアプリケーションがそのメソッドを呼び出す可能性があります。これに対して，メソッドをプロテクトに設定した場合は，アプリケーションはそのメソッドを直接呼び出せません。特定の状態を前提とするメソッドはプロテクトとして宣言し，ほかのパブリックなメソッドであらかじめデータを設定してからそのプロテクトメソッドを呼び出すようにします。

プロパティを実装するメソッドは，仮想プロテクトメソッドとして宣言します。メソッドをそのように宣言すれば，アプリケーション開発者はプロパティの実装をオーバーライドして，その機能の強化または全面的な置き換えができます。このようなプロパティには，十分に多様性があります。アクセスメソッドをプロテクトに保てば，開発者が誤ってアクセスメソッドを呼び出し，プロパティを変更してしまうことはありません。


Abstract methods
Abstract methods1107007

Section topics

メソッドは Delphi コンポーネント内に abstract として宣言されることがあります。VCL で抽象メソッドが発生するのは，TCustomGrid のように名前が「custom」で始まるクラスだけです。下位クラスの派生専用という意味で，そのようなクラス自体が abstract になります。

抽象メンバーが入っているクラスのインスタンスオブジェクトは作成できません。abstract 指令の用途は，下位コンポーネントでの明示と定義が必要なクラスの各部を示すことです。abstract 指令を使った場合，コンポーネントの開発者は下位クラスに抽象メンバーを再宣言してからでないと，クラスの実際のインスタンスを作成できません。


Making methods virtual
Making methods virtual1107008

Section topics	参照

仮想メソッドでは，同一のメソッド呼び出しによって，さまざまなオブジェクト型に固有のコードを実行させることができます。

アプリケーション開発者によって直接使用されるコンポーネントでは，たいていの場合すべてのメソッドは非仮想メソッドとして実装できます。しかし，ほかのコンポーネントの派生元として使用される抽象コンポーネントでは，メソッドを仮想メソッドとして実装することを考慮します。仮想メソッドを使用すれば，派生したコンポーネントで，継承した仮想メソッドをオーバーライドできます。


Declaring methods
Declaring methods1107009

Section topics	参照	例

コンポーネントメソッドの宣言方法は，一般のクラスメソッドの宣言方法と同じです。

コンポーネントに新しいメソッドを宣言する手順は次のとおりです。

コンポーネントのオブジェクト型宣言に宣言を追加する

コンポーネントのユニット implementation でメソッドを実装する


An example of declaring methods
An example of declaring methods1107010

Section topics

2 つの新しいメソッド（静的プロテクトメソッドと仮想パブリックメソッド）を定義するコンポーネントのコード例を次に示します。

type

TSampleComponent = class(TControl)

protected

procedure MakeBigger;	{静的プロテクトメソッドを宣言}

public

function CalculateArea: Integer; virtual;	{ 仮想パブリックメソッドを宣言}

end;

...

implementation

...

procedure TSampleComponent.MakeBigger;	{最初のメソッドを実装}

begin

Height := Height + 5;

Width := Width + 5;

end;

function TSampleComponent.CalculateArea: Integer;	{2 番目のメソッドを実装}

begin

Result := Width * Height;

end;


Using graphics in components
Using graphics in components1105001

Section topics	参照

Windows では，デバイスに依存しないグラフィックを作成するために，強力なグラフィックデバイスインターフェース（GDI）が提供されています。ただし，プログラマが GDI を使用する場合は，グラフィックリソースの管理など数多くの作業が伴います。Delphi は，GDI の使用に伴う退屈な作業をすべて行います。そのため開発者は，見失ったハンドルや未解放のリソースなどにわずらわされることもなく，生産的な作業に専念できます。

Delphi アプリケーションは Windows API のどの GDI 関数でも直接呼び出せます。しかし，Delphi はグラフィック関数をカプセル化し，より速くより簡単なグラフィック作成方法を提供します。

この章では，以下のことを説明します。

グラフィックの概要

キャンバスの使い方

画像の使い方

オフスクリーンビットマップ

変更への応答


Overview of graphics
Overview of graphics1105002

Section topics	参照	例

Delphi では，Windows GDI がいくつかのレベルでカプセル化されています。コンポーネント開発者にとって重要なのは，コンポーネントがどのようにして画面にイメージを表示するかということです。GDI 関数を直接呼び出す場合には，まずデバイスコンテキストのハンドルが必要です。デバイスコンテキストには，ペン，ブラシ，フォントなどの多様な描画ツールを選択しておきます。グラフィックイメージを描画した後は，破棄する前にデバイスコンテキストを元の状態に復元しておかなければなりません。

Delphi では，そうした細かい処理は必要ありません。Delphi のコンポーネントには，グラフィック用の単純で完備したインターフェース，つまり Canvas プロパティがあります。キャンバスは，有効なデバイスコンテキストを用意し，使用後にはそのデバイスコンテキストを解放します。またキャンバスは，現在のペン，ブラシ，フォントを示す独自のプロパティを持っています。

キャンバスがすべてのリソースを開発者にかわって管理するので，開発者はペンハンドルなどの作成，選択，解放に気を使う必要がなくなります。使用するペンの種類をキャンバスに指示しておけば，その後の作業はキャンバスが処理します。

Delphi はリソースを後の使用に備えてキャッシュに入れておくので，繰り返し行う処理のスピードが向上します。これも，グラフィックリソースの管理を Delphi に任せることの効果です。たとえば，あるペンツールを繰り返し作成し，使用し，破棄するプログラムの場合，そのツールを使用するたびに同じ手順を繰り返します。一方，Delphi では，繰り返し使用されるツールはキャッシュにある公算が高いため，Delphi はツールを再作成するかわりに既存のツールを使います。


An example of simplified graphics code
An example of simplified graphics code1105003

Section topics

以下の 2 つのコード例は，Delphi のグラフィックコードがどれほど単純なものかを示しています。最初のコードは，ObjectWindows を使用して開発したアプリケーションです。標準の GDI 関数によって，青色の枠を持つ黄色の楕円をウィンドウに描画しています。2 番目のコードは，Delphi を使用して開発したアプリケーションです。キャンバスを使用して，同じ楕円を描画しています。

procedure TMyWindow.Paint(PaintDC: HDC; var PaintInfo: TPaintStruct);

var

PenHandle, OldPenHandle: HPEN;

BrushHandle, OldBrushHandle: HBRUSH;

begin

PenHandle := CreatePen(PS_SOLID, 1, RGB(0, 0, 255));	{青色のペンを作成}

OldPenHandle := SelectObject(PaintDC, PenHandle);	{DC に青色のペンを使用するように指示}

BrushHandle := CreateSolidBrush(RGB(255, 255, 0));	{黄色のブラシを作成}

OldBrushHandle := SelectObject(PaintDC, BrushHandle);	{DC に黄色のブラシを使用するように指示}

Ellipse(HDC, 10, 10, 50, 50);	{楕円を描画}

SelectObject(OldBrushHandle);	{元のブラシを復元}

DeleteObject(BrushHandle);	{黄色のブラシを削除}

SelectObject(OldPenHandle);	{元のペンを復元}

DeleteObject(PenHandle);	{青色のペンを廃棄}

end;

procedure TForm1.FormPaint(Sender: TObject);

begin

with Canvas do

begin

Pen.Color := clBlue;	{ペンを青色にする}

Brush.Color := clYellow;	{ブラシを黄色にする}

Ellipse(10, 10, 50, 50);	{楕円を描画}

end;

end;


Using the canvas
Using the canvas1105004

Section topics	参照

キャンバスクラスは，いくつかのレベルで Windows グラフィックをカプセル化しています。線，画像，テキストを描画するための高レベルな関数から，キャンバスの描画機能を設定するための中間レベルのプロパティ，さらに Windows GDI への低レベルなアクセス方法まであります。

以下の表に，キャンバスの描画機能を要約して示します。

レベル	動作	ツール
高レベル	線や図形の描画	MoveTo，LineTo，Rectangle，Ellipse などの メソッド
	テキストの表示と寸法の取得	TextOut，TextHeight，TextWidth，TextRect の各メソッド
	領域の塗りつぶし	FillRect メソッドと FloodFill メソッド
中間レベル	テキストとグラフィックのカスタマイズ	Pen，Brush，Font の各プロパティ
	ピクセルの操作	Pixels プロパティ
	イメージのコピー，マージ	Draw，StretchDraw，BrushCopy，CopyRect の各メソッド，CopyMode プロパティ
低レベル	Windows GDI 関数の呼び出し	Handle プロパティ


Working with pictures
Working with pictures1105005

Section topics	参照

Delphi で行うグラフィック作業のほとんどは，コンポーネントやフォームのキャンバスへ直接的に描画する作業です。Delphi では，ビットマップ，メタファイル，アイコンなどのスタンドアロングラフィックイメージも処理できます。この場合，パレットは自動的に管理できます。

Delphi の画像処理について以下の 3 つの項目を説明します。

画像，グラフィック，キャンバスの使い方

グラフィックの読み込みと保存

パレットの使い方


Using a picture, graphic, or canvas
Using a picture, graphic, or canvas1105006

Section topics	参照

以下に示すように，Delphi にはグラフィックを扱う 3 種類のクラスがあります。

キャンバスは，フォーム，グラフィックコントロール，ビットマップ，プリンタのビットマップ描画表面を表します。キャンバスはスタンドアロンのクラスではなく，常にほかのクラスのプロパティとして存在します。

グラフィックは，ビットマップ，アイコン，メタファイルなど，通常はファイルかリソースに格納されているグラフィックイメージを表します。各イメージに対応して，TBitmap，TIcon，TMetafile の各クラスがあります。この 3 つのクラスはともに TGraphic クラスから派生しています。また， 開発者は独自のグラフィッククラスを定義できます。グラフィックに最低限共通の標準的なインターフェースが TGraphic に定義されているので，アプリケーションからはさまざまな種類のグラフィックを容易に使用できます。

画像は，グラフィックのコンテナです。グラフィックのコンテナは，すべてのグラフィッククラスをその中に格納できます。ビットマップ，アイコン，メタファイル，ユーザー定義グラフィック型は，すべて TPicture 型のフィールドに格納できます。アプリケーションは，画像クラスに格納されたさまざまなグラフィック型を，同一の方法で操作できます。たとえば，イメージコントロールは Picture という TPicture 型のプロパティを持っており，それによってさまざまなグラフィック型のイメージを表示します。

画像クラスは常にグラフィッククラスを含んでおり，また，グラフィッククラスはキャンバスクラスを含む場合があります（TBitmap は，キャンバスクラスを含む唯一の標準グラフィッククラスです）。通常，画像クラスを扱う場合は，グラフィッククラスのうち TPicture をとおして操作できる部分だけを使用します。グラフィッククラス固有の細部を操作する場合には，その図形オブジェクトの Graphic プロパティを使用します。


Loading and storing graphics
Loading and storing graphics1105007

Section topics	参照	例

Delphi のすべての画像とグラフィックは，ファイルからイメージを読み込んだり，再度そのファイル（またはほかのファイル）に保存することができます。画像のイメージの読み込みと保存はいつでも行えます。

イメージをファイルから画像に読み込むには，その画像オブジェクトの LoadFromFile メソッドを呼び出します。

イメージを画像からファイルに保存するには，その画像オブジェクトの SaveToFile メソッドを呼び出します。

LoadFromFile と SaveToFile は，唯一のパラメータとしてファイル名を受け取ります。LoadFromFile は，ファイル名の拡張子によって読み込むグラフィックオブジェクトの種類を判定します。SaveToFile は，保存するグラフィックオブジェクト型に合わせてファイルの種類を決定します。


An example of loading a bitmap
An example of loading a bitmap1105008

Section topics

ビットマップをイメージコントロールの画像に読み込むには，次のように，ビットマップファイルの名前を画像オブジェクトの LoadFromFile メソッドに渡します。

procedure TForm1.LoadBitmapClick(Sender: TObject);

begin

Image1.Picture.LoadFromFile('RANDOM.BMP');

end;

画像オブジェクトは，.BMP をビットマップファイルの拡張子として認識し，グラフィックを TBitmap として作成してから，そのグラフィックの LoadFromFile メソッドを呼び出します。このグラフィックはビットマップなので，LoadFromFile メソッドはイメージをビットマップとしてファイルから読み込みます。


Handling palettes
Handling palettes1105009

Section topics	参照

Delphi は，パレットを使用するデバイスでは，自動的にパレットの実現をサポートします。パレットを持つコントロールでは，TControl から継承した 2 つのメソッドによって，Windows がそのパレットを扱う方法を制御できます。

ほとんどのコントロールはパレットとは関係ありません。しかし，イメージコントロールなど，ある種のグラフィックイメージを持つコントロールは，確実に適切な外観で表示されるように，Windows やスクリーンデバイスドライバとやり取りする場合があります。Windows では，この処理をパレットの「実現」と呼びます。

パレットを実現するときは，最前面のウィンドウのすべてのパレット色はそのまま表示されます。背面のウィンドウのパレット色も可能な限りそのまま表示されますが，表示できなかった色については，「実際の」パレットの最も近い色にマッピングされます。Windows は，ウィンドウが互いに前後に移動するのに応じて，継続的にパレットの実現処理を行っています。

メモ	Delphi 自身は，ビットマップ以外については，パレットの作成や操作に対するサポートを提供していません。しかし，パレットハンドルを取得すれば Delphi コントロールがそれを管理できます。


Specifying a palette for a control
Specifying a palette for a control1105010

Section topics	参照

コントロールにパレットを指定するには，そのコントロールの GetPalette メソッドをオーバーライドして，パレットのハンドルを返します。

コントロールにパレットを指定すると，以下の 2 つの処理が行われます。

アプリケーションに，コントロールのパレットを実現する必要があることを通知する

そのパレットを実際に使用するパレットとして指定し，実現する


Responding to palette changes
Responding to palette changes1105011

Section topics	参照

コントロールが GetPalette をオーバーライドしてパレットを指定した場合， Delphi は自動的に，Windows からのパレットメッセージに対して応答します。パレットメッセージを処理するメソッドは PaletteChanged です。

PaletteChanged は，コントロールのパレットを前景と背景のどちらで実現するかを決定します。Windows によるパレットの実現では，前景パレットを最前面のウィンドウが使用し，背景パレットはほかのウィンドウが使用します。しかし，Delphi はそのうえに，コントロールのパレットを 1 つのウィンドウ内でタブ順に実現します。タブ順の先頭にないコントロールに前景パレットを使用させる場合だけ，デフォルトの動作をオーバーライドします。


Offscreen bitmaps
Offscreen bitmaps1105012

Section topics	参照

複雑なグラフィックイメージを描く際に Windows プログラミングでよく使用されるテクニックとして，オフスクリーンビットマップを作成し，そのビットマップ上にイメージを描画してから，完成したイメージを最終目標である画面にコピーする方法があります。画面に直接描画すると画面がちらつく場合がありますが，オフスクリーンイメージを使用すればこのちらつきは減少します。

また，Delphi のビットマップクラスは，通常リソースやファイルのビットマップイメージを表しますが，オフスクリーンイメージとしても使用できます。


Creating and managing offscreen bitmaps
Creating and managing offscreen bitmaps1105013

Section topics	参照

複雑なグラフィックイメージを作成する場合は，画面に表示されているキャンバスに直接描画する方法は採りません。フォームやコントロールのキャンバスに描画するかわりに，ビットマップオブジェクトを作成し，そのキャンバスに描画してから，仕上がったイメージをオンスクリーンのキャンバスにコピーします。

オフスクリーンビットマップは，グラフィックコントロールの Paint メソッドでよく使用されます。ほかの一時オブジェクトと同様，ビットマップを次のように try..finally ブロックで保護します。

type

TFancyControl = class(TGraphicControl)

protected

procedure Paint; override;	{Paint メソッドをオーバーライド}

end;

procedure TFancyControl.Paint;

var

Bitmap: TBitmap;	{オフスクリーンビットマップ用の一時変数}

begin

Bitmap := TBitmap.Create;	{ビットマップオブジェクトを作成}

try

{ ビットマップ上に描画 }

{ 結果をコントロールのキャンバスにコピー }

finally

Bitmap.Free;	{ビットマップオブジェクトを廃棄}

end;

end;


Copying bitmapped images
Copying bitmapped images1105014

Section topics	参照

あるキャンバスからほかのキャンバスへイメージをコピーする場合，4 つの方法があります。各方法に応じて，それぞれのメソッドを呼び出します。

次の表に，キャンバスオブジェクトのイメージコピーメソッドの要約を示します。

処理	メソッド
グラフィック全体をコピー	Draw
グラフィックをコピーしてサイズ変更	StretchDraw
キャンバスの一部をコピー	CopyRect
ラスター演算を適用してビットマップをコピー	BrushCopy


Responding to changes
Responding to changes1105015

Section topics	参照	例

キャンバスや，キャンバスが所有するオブジェクト（ペン，ブラシ，フォント）など，すべてのグラフィックオブジェクトには，オブジェクトの変更に応答するためのイベントがあります。このイベントを使用すれば，コンポーネント（またはコンポーネントを使用しているアプリケーション）を変更に対してイメージの左再描画によって応答させることができます。

グラフィックオブジェクトがコンポーネントの設計時インターフェースの一部としてパブリッシュに宣言されている場合は，そのオブジェクトの変更に応答することが特に重要です。そうしないと，コンポーネントの設計時の外観がオブジェクトインスペクタのプロパティと一致しません。

グラフィックオブジェクトの変更に応答するには，オブジェクトの OnChange イベントにメソッドを指定します。


An example of responding to changes
An example of responding to changes1105016

Section topics

次に示す図形コンポーネントでは，図形を描画するペンやブラシを表すプロパティは，パブリッシュに設定されています。コンポーネントのコンストラクタは，各プロパティの OnChange イベントにメソッドを指定し，ペンやブラシが変更されたときにイメージを更新するようにしています。

type

TShape = class(TGraphicControl)

public

procedure StyleChanged(Sender: TObject);

end;

...

implementation

...

constructor TShape.Create(AOwner: TComponent);

begin

inherited Create(AOwner);	{必ず継承したコンストラクタを呼び出す！}

Width := 65;

Height := 65;

FPen := TPen.Create;	{ペンを作成}

FPen.OnChange := StyleChanged;	{OnChange イベントにメソッドを指定}

FBrush := TBrush.Create;	{ブラシを作成}

FBrush.OnChange := StyleChanged;	{OnChange イベントにメソッドを指定}

end;

procedure TShape.StyleChanged(Sender: TObject);

begin

Invalidate();	{コンポーネントを消去して再描画}

end;


Handling messages
Handling messages1106001

Section topics	参照

従来の Windows プログラミングでは，Windows がアプリケーションに送ってくるメッセージの処理が重要でした。Delphi は開発者にかわって，一般的なメッセージの大半を処理します。ただし，Delphi が処理しないメッセージを扱うときは，開発者がそのメッセージを処理しなければなりません。また，開発者が独自のメッセージを作成する場合もあります。

この章では，メッセージについて以下の 3 項目を説明します。

メッセージ処理機構

メッセージ処理方法の変更

新しいメッセージハンドラの作成


Understanding the message-handling system
Understanding the message-handling system1106002

Section topics	参照

すべての Delphi クラスは，メッセージ処理メソッドまたはメッセージハンドラと呼ばれる，メッセージ処理のためのメカニズムを備えています。メッセージハンドラの基本的な構造は次のとおりです。つまり，クラスがメッセージを受け取ると，そのメッセージに対応するメソッドが呼び出されることで，メッセージがディスパッチされます。対応するメソッドが存在しないメッセージについては，デフォルトのハンドラが使用されます。

次の図は，メッセージディスパッチ機構を示します。

ビジュアルコンポーネントライブラリのメッセージディスパッチ機構は，特定のクラスに向けられたすべての Windows メッセージ（ユーザー定義メッセージを含む）をメソッド呼び出しに変換します。開発者はメッセージディスパッチ機構自体を変更する必要はありません。必要なのは，メッセージ処理メソッドを作成することだけです。


What's in a Windows message?
What's in a Windows message?1106003

Section topics	参照

Windowsのメッセージは，いくつかのフィールドを持つデータレコードです。最も重要なフィールドは，メッセージを識別するための整数値のフィールドです。Windows では多くのメッセージが定義されていますが，Messages ユニットにはそのすべての識別子が宣言されています。メッセージには，ほかに 2 つのパラメータフィールドと 1 つの結果フィールドがあります。

この 2 つのパラメータには，それぞれ 16 ビット値および 32 ビット値が入ります。Windows のコードでは多くの場合，各パラメータの名前はそれぞれ「word parameter」を意味する wParam と，「long parameter」を意味する lParam です。1 つのパラメータが 2 つ以上の情報を持つこともあるので，たとえば，lParamHi によって lParam パラメータの上位ワードを取得する，というような処理が行われることもあります。

従来，Windows プログラマには Windows API においてパラメータの内容についての知識が必要でした。最近になって，マイクロソフト社はパラメータに名前を付けました。このいわゆる「メッセージクラッキング」によって，それぞれのメッセージが伴うパラメータの内容が理解しやすくなりました。たとえば，WM_KEYDOWN メッセージのパラメータは現在では nVirtkey や lKeyData と表されており，wParam や lParam と表すよりもわかりやすくなりました。

Delphi では，メッセージの種類に対応するレコード型をそれぞれ定義することにより，各パラメータにわかりやすい名前を付けています。たとえば，マウスメッセージでは，マウスイベントの発生した x 座標と y 座標が lParam に入ります。つまり，一方の座標が上位ワードに，他方の座標が下位ワードに入っています。しかし，マウスメッセージ構造を使用すれば，各座標がどちらのワードに入っているのかを考える必要はありません。なぜなら，lParamLo と lParamHi のかわりに，XPos と YPos という名前で各座標を参照できるからです。


Dispatching messages
Dispatching messages1106004

Section topics	参照

アプリケーションがウィンドウを作成する場合は，Windows カーネルにウィンドウプロシージャを登録します。このウィンドウプロシージャは，ウィンドウに対して送られるメッセージを処理するルーチンです。ウィンドウプロシージャは通常，そのウィンドウが処理する各メッセージをエントリとする巨大な case 文になります。新しい種類のウィンドウを作成するたびに，完全なウィンドウプロシージャを作成しなければなりません。なお，ここでは「ウィンドウ」という用語で，ウィンドウ，コントロールなど，画面に表示されるさまざまなものを表しています。

Delphi では，以下に示す方法でメッセージのディスパッチが単純化されています。

各コンポーネントは，完全なメッセージディスパッチ機構を継承する

ディスパッチ機構にはデフォルトの処理方法がある。独自の処理を行うメッセージに対してのみ新しいハンドラを定義する

メッセージ処理を少しだけ変更して残りの処理を継承メソッドにまかせることができる

このメッセージディスパッチ機構では，任意のメッセージを任意のコンポーネントに任意の時点で安全に送ることができます。コンポーネントがハンドラを持っていないメッセージはデフォルトの方法で処理されます。

Tracing the flow of messages1106005

Delphi では，アプリケーションの各コンポーネント型のウィンドウプロシージャとして，MainWndProc という名前のメソッドが登録されます。MainWndProc には例外処理ブロックがあります。ここで，Windows からのメッセージ構造を WndProc という仮想メソッドに渡します。また，アプリケーションクラスの HandleException メソッドを呼び出すことですべての例外を処理します。

MainWndProc は非仮想メソッドで，特定のメッセージに対する処理を行いません。各コンポーネント型はこのメソッドをオーバーライドできるので，カスタマイズは WndProc で行われます。

WndProc メソッドは，処理に影響するような状態について検査し，不要なメッセージを「トラップ」します。たとえば，コンポーネントはマウスのドラッグ中，キーボードイベントを無視します。そのため，TWinControl の WndProc メソッドはコンポーネントがドラッグされていないときにのみ，キーボードイベントを次に渡します。最終的に WndProc は，TObject から継承した非仮想メソッド Dispatch を呼び出します。Dispatch メソッドは，メッセージを処理するメソッドを決定して呼び出します。

Dispatch は，メッセージをディスパッチする方法を決定するのに，メッセージ構造の Msg フィールドを使用します。コンポーネントがそのメッセージに対するハンドラを定義している場合には，Dispatch はそのメソッドを呼び出します。コンポーネントがそのメッセージに対するハンドラを定義していない場合には，Dispatch は DefaultHandler を呼び出します。


Changing message handling
Changing message handling1106006

Section topics	参照

コンポーネントのメッセージ処理方法を変更する前に，本当に変更する必要があるのかどうかを確認してください。Delphi は大部分の Windows メッセージを，コンポーネント開発者とコンポーネントユーザーの両方が処理できるイベントに変換します。たいていの場合は，メッセージ処理の動作を変更するよりも，イベント処理の動作を変更する方が適切です。

メッセージ処理方法を変更するには，メッセージ処理メソッドをオーバーライドします。また，メッセージをトラップすることにより，特定の状況下ではコンポーネントがメッセージを処理しないようにすることもできます。


Overriding the handler method
Overriding the handler method1106007

Section topics	参照	例

コンポーネントがメッセージを処理する方法を変更するには，そのメッセージに対応するメッセージ処理メソッドをオーバーライドします。コンポーネントがそのメッセージに対応するメソッドを持っていない場合には，メッセージ処理メソッドを新しく宣言します。

メッセージ処理メソッドをオーバーライドするには，オーバーライドするメソッドと同じメッセージインデックスを持つ新しいメソッドをコンポーネントで宣言します。override 指令ではなく message 指令を使用し，一致するメッセージインデックスを指定します。

メソッドの名前も var パラメータの型も，オーバーライドされるメソッドと一致させる必要はありません。一致させるのは，メッセージインデックスだけです。ただし，メッセージ処理メソッドの名前を，それが処理するメッセージを表すように付ければ，コードがわかりやすくなります。


An example of overriding a message handler
An example of overriding a message handler1106008

Section topics

たとえば，コンポーネントの WM_PAINT メッセージの処理をオーバーライドするには，次のように WMPaint メソッドを再宣言します。

type

TMyComponent = class(...)

...

procedure WMPaint(var Message: TWMPaint); message WM_PAINT;

end;


Using message parameters
Using message parameters1106009

Section topics	参照	例

メッセージ処理メソッドの実行中，コンポーネントはそのメッセージ構造のすべてのパラメータにアクセスできます。メッセージハンドラに渡されるパラメータは var パラメータなので，ハンドラは必要な場合にパラメータの値を変更できます。Result フィールドは，変更することの多いパラメータです。Result は，メッセージを送った SendMessage から返される値です。

メッセージ処理メソッドの Message パラメータの型は，メッセージによって変化します。個々のパラメータの名前と意味については，Windows メッセージに関するマニュアルを参照してください。なんらかの理由で，メッセージパラメータを旧式の名前（WParam，LParam など）で参照する場合は，Message を TMessage に型キャストします。TMessage 型では，メッセージパラメータは旧式の名前で参照されます。


Trapping messages
Trapping messages1106010

Section topics	参照	例

あるコンポーネントについて，特定の状況下ではメッセージを無視させたい場合があります。つまり，コンポーネントがそのメッセージをハンドラにディスパッチしないようにするわけです。メッセージをトラップするには，WndProc という仮想メソッドをオーバーライドします。

WndProc メソッドは，メッセージをフィルタにかけて選別してから Dispatch メソッドに渡します。その後，Dispatch メソッドがメッセージを処理するメソッドを決定します。WndProc をオーバーライドすれば，ディスパッチされる前にメッセージを選別できます。TWinControl から派生したコントロールの WndProc をオーバーライドするコードは次のとおりです。

procedure TMyControl.WndProc(var Message: TMessage);

begin

{処理の継続を決定するための条件}

inherited WndProc(Message);

end;

TControl コンポーネントでは，ユーザーがコントロールをドラッグアンドドロップしているときは，すべてのマウスメッセージにフィルタをかけて特別な処理を行います。WndProc をオーバーライドする方法には，以下の 2 つの利点があります。

ハンドラを個別に指定するかわりに，メッセージのある範囲全体に対してフィルタをかけられる

メッセージがディスパッチされないので，ハンドラはまったく呼び出されない


TheWndProc method
TheWndProc method1106011

Section topics

次のコードは，TControl の WndProc メソッドの一部分です。

procedure TControl.WndProc(var Message: TMessage);

begin

...

if (Message.Msg >= WM_MOUSEFIRST) and (Message.Msg <= WM_MOUSELAST) then

if Dragging then	{ドラッグを特別な方法で処理}

DragMouseMsg(TWMMouse(Message))

else

...	{それ以外は普通に処理}

end;

...	{それ以外は普通に処理}

end;


Creating new message handlers
Creating new message handlers1106012

Section topics	参照

Delphi では，よく使用される Windows メッセージのほとんどに対してハンドラが用意されています。しかし，独自のメッセージを定義したときは，開発者自身が新しいメッセージハンドラを作成しなければなりません。ユーザー定義メッセージについて，以下の 2 項目を説明します。

独自のメッセージの定義

新しいメッセージ処理メソッドの宣言


Defining your own messages
Defining your own messages1106013

Section topics	参照

多くの標準コンポーネントでは，内部で使用するためのメッセージが定義されています。メッセージを定義する一般的な目的は，標準 Windows メッセージでは扱われていない情報や，状態の変更を通知することです。

メッセージを定義する手順は次のとおりです。

1.	メッセージ識別子の宣言

2.	メッセージレコード型の宣言


Declaring a message identifier
Declaring a message identifier1106014

Section topics	参照	例

メッセージ識別子は整数の定数です。Windows ではシステム用に 1024 未満のメッセージ識別子が予約されているので，開発者が独自のメッセージを宣言する場合は，それ以上の番号を付けます。

定数 WM_USER は，ユーザー定義メッセージの開始番号を表しています。メッセージ識別子を定義する場合は，WM_USER 以上の番号を使用します。

ただし，ある種の標準 Windows コントロールは，ユーザー定義用の範囲の番号を使用することがあります。そのようなコントロールとしては，リストボックス，コンボボックス，編集ボックス，コマンドボタンがあります。このようなコントロールから派生させたコンポーネントで新しいメッセージを定義する場合には，必ず Messages ユニットで Windows がそのコントロールに対して定義しているメッセージの番号を確認してください。


An example of user-defined messages
An example of user-defined messages1106015

Section topics

次のコード例は，2 つのユーザー定義メッセージの定義を示しています。

const

WM_MYFIRSTMESSAGE = WM_USER + 400;

WM_MYSECONDMESSAGE = WM_USER + 401;


Declaring a message-record type
Declaring a message-record type1106016

Section topics	参照	例

メッセージのパラメータに名前を付ける場合には，そのメッセージのレコード型を宣言します。メッセージレコード型は，メッセージ処理メソッドに渡されるパラメータの型です。メッセージのパラメータを使用しない場合や，旧式のパラメータ表記方法（wParam，lParam など）を使用する場合には，デフォルトのメッセージレコードである TMessage を使用します。

メッセージレコード型を宣言するときは次の命名規則に従います。

1.	型の名前は，そのメッセージの名前の先頭に T を加えたものにする

2.	まず，最初のフィールドとして TMsgParam 型の Msg を定義する

3.	次の 2 バイトは，パラメータ Word に対応し，その次の 2 バイトは使わないように定義する

または，

次の 4 バイトは，パラメータ Longint に対応するように定義する

4.	最後に，Longint 型のフィールド Result を定義する

たとえば，すべてのマウスメッセージ用のメッセージレコード TWMMouse の例を次に示します。TWMMouse では，可変レコードを使って 1 つのパラメータに 2 組のフィールドを定義しています。

type

TWMMouse = record

Msg: TMsgParam; {最初のフィールドはメッセージ ID}

Keys: Word; {これが wParam}

case Integer of {lParam を参照するには 2 つの方法がある}

0: {

XPos: Integer; {x 座標と y 座標か ...}

YPos: Integer);

1: {

Pos: TPoint; {...1 つの点}

Result: Longint); {最後は Result フィールド}

end;


Declaring a new message-handling method
Declaring a new message-handling method1106017

Section topics	参照	例

新しいメッセージ処理メソッドの宣言が必要になるのは以下の 2 つの場合です。

標準コンポーネントが処理できない Windows メッセージを，開発するコンポーネントで処理する場合

開発するコンポーネントで使用するために独自のメッセージを定義した場合

メッセージ処理メソッドを宣言する手順は以下のとおりです。

1.	コンポーネントのクラス宣言の protected 部でメソッドを宣言します。

2.	メソッドを手続きにします。

3.	処理するメッセージの名前に基づいてメソッドを命名します。なお，アンダーライン文字があれば，それを取り除きます。

4.	唯一の var パラメータとして，メッセージレコード型の Message を指定します。

5.	メッセージメソッド実装内で，コンポーネント独自の処理コードを記述します。

6.	継承メッセージハンドラを呼び出します。


An example of a message handler
An example of a message handler1106018

Section topics

ユーザー定義メッセージ CM_CHANGECOLOR のためのメッセージハンドラの宣言例を，次に示します。

const

CM_CHANGECOLOR = WM_USER + 400;

type

TMyComponent = class(TControl)

...

protected

procedure CMChangeColor(var Message: TMessage): message CM_CHANGECOLOR;

end;

procedure TMyComponent.CMChangeColor(var Message: TMessage);

begin

Color := Message.lParam;

inherited;

end;


Registering components
Registering components1117001

Section topics	参照

コンポーネントは，登録してからでないと IDE にインストールできません。コンポーネントをインストールしておけば，設計時にコンポーネントパレットからコンポーネントを選択し，フォームに配置し，操作できます。

コンポーネントを，設計時にも操作できるものにするための手順は次のとおりです。

コンポーネントの登録

パレットビットマップの追加

プロパティとイベントについてのヘルプの提供

プロパティの保存と読み込み

ただし，コンポーネントによっては，上の手順の一部は必要ありません。たとえば，新しいプロパティやイベントを定義しなかった場合は，ヘルプを提供する必要はありません。常に必要なのは，Delphi への登録だけです。


Registering components
Registering components1117002

Section topics	参照

登録はユニット単位で行います。1 つのユニットに複数のコンポーネントを作成した場合は，そのコンポーネントは一度に登録されます。

コンポーネントを登録するには，コンポーネントユニットに手続き Register を記述します。この作業について以下の 2 つの項目を説明します。

Register 手続きの宣言

Register 手続きの実装

登録を終えた後，コンポーネントをコンポーネントパレットにインストールします。コンポーネントのインストールについては『ユーザーズガイド』の説明を参照してください。


Declaring the Register procedure
Declaring the Register procedure1117003

Section topics

コンポーネントを登録するには，コンポーネントのユニットに Register という名前の手続きを記述します。Register の宣言は必ずユニットのインターフェース部に記述します。この Register の中で，登録する各コンポーネントについて RegisterComponents を呼び出します。

新しいコンポーネントを作成して登録する簡単なユニットを次に示します。

unit MyBtns;

interface

type

{ここでコンポーネント型を宣言}

procedure Register; {この文は必ずインターフェース部に記述する}

implementation

{ここでコンポーネントを実装}

procedure Register;

begin

{コンポーネントを登録}

end;

end.


Implementing the Register procedure
Implementing the Register procedure1117004

Section topics

コンポーネントが所属するユニットの手続き Register の中で，コンポーネントパレットに追加する各コンポーネントを登録します。ユニットに複数のコンポーネントがある場合は，すべてのコンポーネントをまとめて一度に登録できます。

コンポーネントを登録するには，コンポーネントを追加するコンポーネントパレットのそれぞれのページに対して手続き RegisterComponents を呼び出します。RegisterComponents は，2 つの重要な情報を Delphi に通知します。

インストールするコンポーネントの名前

コンポーネントをインストールするパレットページの名前

パレットページの名前は文字列で指定します。指定した名前のパレットページが存在しない場合は，Delphi はその名前のページを新しく作成します。Delphi では，標準のパレットページの名前は文字列リストリソースに格納されており，製品の国際化対応バージョンでページの名前を個別の言語でも設定できるようになっています。標準のパレットページにあるコンポーネントをインストールする場合，そのページの名前を得るためには，LoadStr 関数を呼び出してそのページの文字列リソースを表す定数（たとえば System ページなら srSystem）を渡す必要があります。

コンポーネントの名前はオープン配列で渡します。この配列は RegisterComponents の呼び出し文の中で作成できます。

手続き Register の例を次に示します。TMyComponent という名前のコンポーネントを登録し，Miscellaneous という名前のコンポーネントパレットページにそのコンポーネントを配置します。

procedure Register;

begin

RegisterComponents('Miscellaneous', [TMyComponent]);

end;

また，複数のコンポーネントを同じページに一度に登録したり，複数のコンポーネントを複数のページに登録することもできます。次にそのような例を示します。

procedure Register;

begin

RegisterComponents('Miscellaneous', [TFirst, TSecond]); {このページに 2 つ}

RegisterComponents('Assorted', [TThird]); {別のページに 1 つ}

RegisterComponents(LoadStr(srStandard), [TFourth]); {Standard ページにも 1 つ}

end;


Adding palette bitmaps
Adding palette bitmaps1117005

Section topics	参照	例

すべてのコンポーネントには，そのコンポーネントをコンポーネントパレットで表示するためのビットマップが必要です。独自のビットマップを指定しなければ，デフォルトのビットマップが使用されます。

パレットビットマップが必要なのは設計時だけなので，パレットビットマップをコンポーネントのユニット中にコンパイルする必要はありません。パレットビットマップは Windows リソースファイルで提供します。ファイルの名前は，ユニットと同じ名前に拡張子 .DCR（Dynamic Component Resource）を付けたものにします。リソースファイルは Delphi のイメージエディタで作成できます。ビットマップの大きさは 24 ピクセル四方にします。

インストールする各コンポーネントに 1 つずつパレットビットマップファイルを作成し，そのファイル内に，登録する各コンポーネントに 1 つずつビットマップを作成します。このビットマップイメージにはコンポーネントと同じ名前を付けます。パレットビットマップファイルは，コンパイル済みのユニットと同じディレクトリに入れておきます。こうすれば，コンポーネントをコンポーネントパレットにインストールする際に Delphi がビットマップを探し出せます。


An example of adding a palette bitmap
An example of adding a palette bitmap1117006

Section topics

たとえば，ユニット ToolBox でコンポーネント TMyControl を作成した場合は，TOOLBOX.DCR という名前のリソースファイルに TMYCONTROL という名前のビットマップを作成します。リソース名では大文字と小文字は区別されませんが，通常は大文字を使用します。


Providing Help for your component
Providing Help for your component1117007

Section topics

一般に，フォームで標準コンポーネントを選択したときや，オブジェクトインスペクタでプロパティやイベントを選択したときに〔F1〕キーを押すと，その項目についてのヘルプが呼び出されます。開発したコンポーネントにヘルプファイルを用意しておけば，開発者は同じようにヘルプを利用できます。

開発したコンポーネントについての情報だけを入れた小さなヘルプファイルを用意すれば，その情報を簡単に検索できます。つまり，作成したヘルプファイルは総合的な Delphi ヘルプシステムの一部に組み込まれます。


Creating the Help file
Creating the Help file1117008

Section topics

Windows ヘルプファイルの作成には，どのツールでも使えます。Delphi には，ヘルプファイルをコンパイルし，オンラインヘルプのオーサリングガイドを提供する Microsoft Help Workshop が用意されています。

ライブラリのほかのコンポーネントのヘルプファイルと同じように動作するヘルプファイルを作成するときは，以下の規則に従います。

1.	各コンポーネントに画面を 1 つずつ割り当てる

コンポーネント画面では，そのコンポーネントが宣言されているユニットを示し，コンポーネントの目的を簡単に説明し，コンポーネントユーザーが使用できるすべてのプロパティ，イベント，メソッドを別々にリストします。アプリケーション開発者は，フォームでそのコンポーネントを選択して〔F1〕キーを押すことにより，この画面を表示します。コンポーネント画面の実際の例を表示するには，フォームに任意のコンポーネントを配置して〔F1〕キーを押します。

コンポーネント画面には，キーワード検索用の脚注文字「K」を付けて，コンポーネントの名前を指定します。たとえば，TMemo コンポーネントのキーワード脚注は「TMemo」となります。

2.	コンポーネント内に宣言されている各プロパティ，イベント，メソッドに画面を 1 つずつ割り当てる

プロパティ，イベント，メソッドの各画面には，その項目の宣言を示し，使用方法を説明します。アプリケーション開発者は，オブジェクトインスペクタでその項目を強調表示させて〔F1〕キーを押すか，またはコードエディタでその項目の名前にカーソルを移動させて〔F1〕キーを押すことにより，その項目の画面を表示します。プロパティ画面の実際の例を表示するには，オブジェクトインスペクタで任意のプロパティを選択して〔F1〕キーを押します。

コンポーネント，プロパティ，イベント，メソッドの各画面には，以下の脚注を入れます。

脚注「#」として入力される，トピックごとのトピック ID

脚注「$」として入力されるタイトル

タイトルは，［Topics Found］ダイアログボックス，［Bookmark］ダイアログボックス，［History］ウィンドウに指定されているように表示されます。

項目名を含んでいるキーワード検索のための脚注「K」

たとえば，Top プロパティのキーワード脚注は「Top」になります。TMemo の場合，キーワードは「TMemo」になります。


Providing context sensitivity for your component
Providing context-sensitive help for your component1117009

Section topics	参照

Delphi コンポーネントに状況感知型ヘルプを提供するには，次の作業を行う必要があります。

RTF ソースファイルに A 脚注を挿入する

DELPHI3.CFG ファイルに LINK 文を追加する

CNT ファイルに INCLUDE 文を追加する

A 脚注は，ユーザーがコンポーネントまたはプロパティを選択して〔F1〕を押したときにどのトピックを表示するかを決めるために使われます。各コンポーネント，プロパティ，およびイベントのトピックには，以下に示す規約に従った A 脚注が付けなければなりません。

A 脚注の規約

コンポーネント用のヘルプトピックの A 脚注は，次の構文を使って，2 つのエントリをセミコロンで区切って指定します。

<コンポーネント名>_Object;<コンポーネント名>

<コンポーネント名> はコンポーネントの実際の名前です。

たとえばコンポーネントの名前が TFileDialog であれば，A 脚注は次のようになります。

TFileDialog_Object;TFileDialog

プロパティ用のヘルプトピックの A 脚注は，次の構文を使って，3 つのエントリをセミコロンで区切って指定します。

<コンポーネント名>_<プロパティ名>;<プロパティ名>_Property;<プロパティ名>

イベント用の A 脚注もプロパティと同様です。

<コンポーネント名>_<イベント名>;<イベント名>_Event;<イベント名>

<コンポーネント名> はコンポーネントの名前，<プロパティ名> および <イベント名> はそれぞれプロパティおよびイベントの名前です。

たとえば，MyGrid というコンポーネントの BackgroundColor プロパティ用の A 脚注は次のようになります。

MyGrid_BackgroundColor;BackgroundColor_Property;BackgroundColor

ヘルプファイルと CNT ファイルを DELPHI3.CFG ファイルにリンクする

状況感知型ヘルプを Delphi IDE にリンクするには，さらに 2 つの作業を行います。

DELPHI3.CFG の Third-Party Help セクションに，ヘルプファイルを参照する LINK 文を追加する

［例］ : :Link 3RDPARTY.HLP

ヘルプの CNT ファイルに，DELPHI3.CFG を示す INCLUDE 文を追加する

［例］ : :Include DELPHI3.CFG


Storing and loading properties
Storing and loading properties1117010

Section topics	参照

Delphi はフォームとそのコンポーネントをフォーム（.DFM）ファイルに格納します。フォームファイルには，フォームとコンポーネントプロパティがバイナリ形式で保存されます。フォームが保存されるとき，フォームに配置されたコンポーネントは自身のプロパティをフォームファイルに書き込みます。同様に，Delphi に読み込まれるときや，アプリケーションの一部として実行されるときには，コンポーネントは自身をフォームファイルから復元します。

コンポーネントはバイナリ表現の保存と読み込みの機能を継承しているため，ほとんどの場合，何もしなくてもコンポーネントでフォームファイルを操作できます。しかし，コンポーネントが自身を保存する方法や，読み込まれたときの初期化方法を変更したい場合があります。そのためには，基礎的なメカニズムについてある程度理解する必要があります。

プロパティの保存と読み込みについて以下のことを説明します。

保存と読み込みのメカニズム

デフォルト値の指定

保存対象の決定

読み込み後の初期化


Using the store-and-load mechanism
Using the store-and-load mechanism1117011

Section topics	参照

フォームの記述には，フォームのプロパティのリストと，フォーム内の各コンポーネントの同様の記述があります。フォームやコンポーネントは，自身の記述の保存と読み込みを行う機能を備えています。

通常，コンポーネントが自身の記述を保存する場合は，パブリックまたはパブリッシュに宣言されているプロパティのうち，値がデフォルトと異なるものを宣言順に書き込みます。コンポーネントが自身の記述を読み込む場合は，まず自身を作成し，すべてのプロパティをデフォルト値に設定してから，保存されている（デフォルト値ではない）プロパティ値を読み込みます。

ほとんどの場合，このデフォルトのメカニズムを変更する必要はありません。しかし，特定のコンポーネントの保存と読み込みの処理をカスタマイズする方法もいくつか用意されています。


Specifying default values
Specifying default values1117012

Section topics	参照	例

Delphi コンポーネントは，値がデフォルトと異なっているプロパティだけを保存します。特に指定しなければ，プロパティはデフォルト値を持っていないとみなされ，そのプロパティは値にかかわらず常に保存されます。

プロパティのデフォルト値を指定するには，プロパティ宣言文の最後に default 指令とデフォルト値を記述します。

プロパティを再宣言するときも，デフォルト値を指定できます。実際，異なったデフォルト値を指定するためにプロパティを再宣言することもよくあります。

メモ	デフォルト値を指定しただけで，オブジェクトの作成時にその値が自動的にプロパティに代入されるわけではありません。コンポーネントのコンストラクタが必要な値を代入するようにしなければなりません。プロパティの値は，コンポーネントのコンストラクタで設定されない場合はゼロ，つまりプロパティの記憶域が 0 に設定されたときにそのプロパティが取る値に必ずなります。したがってデフォルト値は，数値の場合は 0，論理値の場合は False，ポインタの場合は nil という具合になります。ゼロとみなされる値に確信が持てない場合は，コンストラクタメソッドで値を代入します。


An example of specifying a default value
An example of specifying a default value1117013

Section topics

次のコード例では，コンポーネント宣言で Align プロパティにデフォルト値を指定し，コンポーネントコンストラクタでそのデフォルト値を実際に代入しています。新しいコンポーネントは，標準パネルコンポーネントを変更して，ウィンドウのステータスバーとして使用します。そのため，ウィンドウのデフォルトの配置をオーナーの下部として指定します。

type

TStatusBar = class(TPanel)

public

constructor Create(AOwner: TComponent); override; {新しいデフォルトを設定するためオーバーライド}

published

property Align default alBottom; {新しいデフォルト値で再宣言}

end;

...

constructor TStatusBar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); {継承した初期化処理を実行}

Align := alBottom; {Align に新しいデフォルト値を代入}

end;


Determining what to store
Determining what to store1117014

Section topics	参照	例

コンポーネントのプロパティのそれぞれについて，保存するかどうかを指定できます。デフォルトでは，クラス宣言の published 部のすべてのプロパティが保存されますが，特定のプロパティを保存しないように指定したり，プロパティを保存するかどうかを実行時に決定する関数を指定することができます。

プロパティを保存するかどうかを指定するには，そのプロパティの宣言に stored 指令を追加し，その後に True か False，または論理値を返すメソッドの名前を記述します。


An example of stored properties
An example of stored properties1117015

Section topics

次のコードでは，コンポーネントで 3 つの新しいプロパティを宣言しています。最初のプロパティは必ず保存され，2 番目のプロパティは常に保存されず，3 番目のプロパティはメソッドが返す論理値に応じて保存されます。

type

TSampleComponent = class(TComponent)

protected

function StoreIt: Boolean;

public {通常，格納されない}

property Important: Integer stored True;	{常に保存される}

published {通常，常に格納される}

property Unimportant: Integer stored False;	{常に保存されない}

property Sometimes: Integer stored StoreIt;	{関数値に応じて保存}

end;


Initializing after loading
Initializing after loading1117016

Section topics	参照

コンポーネントは，すべてのプロパティ値を保存されている記述から読み込んだ後，Loaded という仮想メソッドを呼び出します。この仮想メソッドは，必要な初期化を行います。Loaded はフォームやコントロールが表示される前に呼び出されるので，初期化処理によって画面にちらつきが生じることはありません。

プロパティが読み込まれた後でコンポーネントを初期化する場合には，Loaded メソッドをオーバーライドします。

メモ	新しい Loaded メソッドでは，まず継承した Loaded メソッドを呼び出します。そうすれば，独自の初期化を行う前に，すべての継承プロパティを適切に初期化できます。

次に示すコードは，TDatabase コンポーネントのコードを元にしています。このデータベースは，読み込まれた後，すべての接続を保存時の状態に戻そうとします。また，接続処理中に例外が発生した場合の処理方法も指定しています。

procedure TDatabase.Loaded;

begin

inherited Loaded; {継承メソッドを最初に呼び出す}

try

if FStreamedConnected then Open {接続を再確立する}

else CheckSessionName(False);

except

if csDesigning in ComponentState then {設計時ならば ...}

Application.HandleException(Self)	 {Delphi に例外を処理させる}

else raise; {そうでない場合には，例外を生成}

end;

end;


Creating packages
Creating packages1114001

Section topics 	参照

コンポーネントを IDE にインストールするには，そのコンポーネントをまずパッケージとしてコンパイルしなければなりません。パッケージは，Delphi アプリケーションと Delphi IDE のいずれか一方または両方が使う特殊なダイナミックリンクライブラリ（DLL）です。パッケージには 1 つまたは複数のコンポーネントのほかに，カスタムプロパティエディタを入れることができます。パッケージをほかの DLL と区別するために，コンパイル済みのパッケージは .DPL（Delphi パッケージライブラリ）という拡張子の付いたファイルに格納されます。

パッケージの作成では以下のことを行います。

コンポーネントのソースコードの入ったユニットファイルを記述する

ユニットファイルの入ったパッケージソースファイルを編集する

パッケージ内でほかのパッケージへの循環参照または冗長なソースコードの使用がないことを確認する

パッケージを DPL にコンパイルする

必要であればパッケージコレクションを作成する。パッケージコレクションを使うとコンポーネントをほかの開発者に配布しやすくなる


Runtime and design-time packages
Runtime and design-time packages1114002

Section topics 	参照

Delphi のコンポーネントパッケージは実行時用または設計時用にコンパイルできます。実行時パッケージは，ユーザーがアプリケーションを実行するときに機能を提供します。設計時パッケージは，コンポーネントパレットへのコンポーネントのインストールや，カスタムコンポーネント用の特殊なプロパティエディタの作成に使います。

コンポーネントをコンポーネントパレットにインストールするには，そのコンポーネントを設計時パッケージとしてコンパイルしなければなりません。新規コンポーネントのデフォルトのコンテナとして，DCLUSR30 パッケージが提供されます。

実行時パッケージを使うかどうかは任意ですが，使うだけの理由は十分にあります。コンポーネントを実行時パッケージにコンパイルすることにより，そのコンポーネントをアプリケーション間で共有できます。アプリケーションには実行可能ファイルに結合されたコンポーネントの個々のコピーがないため，実行可能ファイルがはるかに小さくなり，システムリソースもハードディスク記憶域も節約できます。さらに，実行時パッケージを使うと構築ごとにアプリケーション独自のコードだけがコンパイルされるため，コンパイル速度が向上します。

単一パッケージは設計時と実行時のどちらでも機能し，また場合によって設計時パッケージは実行時パッケージを呼び出すことによって動作することもあります。設計時パッケージには，IDE が必要とする実行時には不要なコードが含まれるので，通常は各コンポーネントパッケージは設計時用と実行時用に分けてコンパイルするのが望ましい使い方です。


See also1114003

パッケージの使い方


Modifying an existing component
Modifying an existing component1108001

Section topics 	参照

コンポーネントの最も簡単な作成方法は，必要な機能の大部分を含むコンポーネントを派生元にして，必要な変更を施すことです。標準のメモコンポーネントを変更して，デフォルトでワードラップを行わないように設定したメモを作成する単純なサンプルを次に示します。

メモコンポーネントの WordWrap プロパティの初期値は True です。しかし，ワードラップを行わないメモをよく使用する場合には，デフォルトでワードラップを行わないように設定したメモを作成できます。

メモ	既存のコンポーネントのパブリッシュプロパティを変更したり特定のイベントハンドラを保存するには，新規クラスを作成するよりもコンポーネントテンプレートを使う方が多くの場合簡単です。

既存のコンポーネントを変更する手順は以下のとおりです。

コンポーネントの作成と登録

コンポーネントオブジェクトの変更


Creating and registering the component
Creating and registering the component1108002

Section topics 	参照

コンポーネントの作成は常に同じ方法で開始します。ユニットを作成し，コンポーネントクラスを派生させて登録し，それをコンポーネントパレットにインストールします。

このサンプルでは，一般的な手順でコンポーネントを作成します。このコンポーネントに固有の点は以下のようになります。

コンポーネントユニットの名前は Memos にする

TMemo から TWrapMemo という新しいコンポーネント型を派生させる

TWrapMemo をコンポーネントパレットの［Samples］ページに登録する

作成したユニットのコードは次のとおりです。

unit Memos;

interface

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

Forms, StdCtrls;

type

TWrapMemo = class(TMemo)

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents('Samples', [TWrapMemo]);

end;

end.

この状態でコンパイルしてインストールすると，TWrapMemo は上位コンポーネントの TMemo とまったく同じように動作します。次の節では，このコンポーネントに簡単な変更を加えます。


Modifying the component class
Modifying the component class1108003

Section topics 	参照

新しく作成したコンポーネントクラスはさまざまな方法で変更できます。しかしこのサンプルでは，メモコンポーネントの 1 つのプロパティの初期値を変更するだけです。これには，以下のようにコンポーネントクラスに 2 つの小さな変更を加えます。

コンストラクタをオーバーライドする

プロパティのデフォルト値を宣言する

コンストラクタは実際にプロパティの値を設定します。デフォルトは，フォーム（.DFM）ファイルに格納する値を Delphi に知らせます。Delphi はデフォルトと異なる値だけを保存するので，両方の作業を実行することが重要です。


Overriding the constructor
Overriding the constructor1108004

Section topics 	参照

すべてのコンポーネントは，作成されたときにプロパティの初期値を設定します。設計時にコンポーネントをフォームに配置した場合または実行時にアプリケーションでコンポーネントを作成した場合，コンポーネントのコンストラクタがプロパティ値を設定します。コンポーネントをフォームファイルからロードした場合，アプリケーションは設計時に変更されたプロパティを設定します。

メモ	コンストラクタをオーバーライドした場合，新しいコンストラクタで独自の処理を行う前に，必ず継承コンストラクタを呼び出します。このサンプルのコンポーネントは，TMemo から継承したコンストラクタをオーバーライドし，WordWrap プロパティを False に設定します。これには，forward 宣言にコンストラクタのオーバーライドを追加し，ユニットの実現部に新しいコンストラクタを記述します。この様子を次に示します。

type

TWrapMemo = class(TMemo)

public { コンストラクタは常にパブリックに設定 }

constructor Create(AOwner: TComponent); override; { この構文は常に同じ }

end;

...

constructor TWrapMemo.Create(AOwner: TComponent); { これは実現部に記述する }

begin

inherited Create(AOwner); { 必ず最初にこの呼び出しを実行 }

WordWrap := False; { 新しい値を設定 }

end;

これで，この新しいコンポーネントはコンポーネントパレットにインストールでき，さらにフォームに追加できます。WordWrap プロパティの初期値は False に設定されています。

プロパティの初期値を変更した場合には，その値をデフォルト値として宣言する必要があります。コンストラクタが設定する値と，デフォルト値として宣言した値が一致していないと，Delphi はプロパティ値を適切に保存および復元できません。


Specifying the new default property value
Specifying the new default property value1108005

Section topics 	参照

Delphi は，フォームのデータをフォームファイルに保存する際，デフォルト値と異なる値のプロパティしか保存しません。こうすることでフォームファイルの容量が小さくなり，フォームの読み込みも高速化されます。このため，プロパティを作成したりデフォルト値を変更した場合は，そのプロパティの新しいデフォルト値を宣言します。フォームファイル，プロパティの読み込み，デフォルト値についての詳細は「コンポーネントの登録」を参照してください。

プロパティのデフォルト値を宣言するには，そのプロパティの名前を再宣言して default 指令と新しい値を記述します。プロパティ全体を宣言する必要はありません。再宣言するのは，プロパティの名前とデフォルト値だけです。

次に，メモコンポーネントを変更してワードラップを行わないようにする例を示します。オブジェクト宣言の published 部で WordWrap プロパティを再宣言し，デフォルト値として False を記述しています。

type

TWrapMemo = class(TMemo)

...

published

property WordWrap default False;

end;

プロパティのデフォルト値を指定しただけではコンポーネントの動作は変化しません。コンポーネントのコンストラクタで値を初期化することも必要です。デフォルト値を再宣言すると，Delphi には WordWrap をフォームファイルに書き込む時期がわかります


See also1108006

コンポーネントの登録

TMemo.


Creating a graphic component
Creating a graphic component1118001

Section topics 	参照

グラフィックコントロールは単純なコンポーネントです。純粋なグラフィックコントロールはフォーカスを受け取らないので，ウィンドウハンドルは必要ありません。ユーザーはマウスでグラフィックコントロールを操作できます。しかし，キーボードインターフェースは備えていません。

この章でとりあげるグラフィックコンポーネント TShape は，コンポーネントパレットの［Additional］ページに表示される図形コンポーネントです。作成するコンポーネントは標準の図形コンポーネントと同じものですが，識別子が重複しないように標準コンポーネントとは異なる名前を付けます。この章では，図形コンポーネントを TSampleShape と命名し，そのコンポーネントの作成について説明します。

1.	コンポーネントの作成と登録

2.	継承プロパティの公開

3.	グラフィック機能の追加


Creatingand registering the component
Creating and registering the component1118002

Section topics 	参照

コンポーネントの作成は常に同じ方法で開始します。ユニットを作成し，コンポーネントクラスを派生させて登録し，コンパイルしてコンポーネントパレットにインストールします。

このサンプルでは，一般的な手順でコンポーネントを作成します。コンポーネントに固有の点は以下のとおりです。

コンポーネントユニットの名前は Shapes とする

TGraphicControl から TSampleShape という新しいコンポーネント型を派生させる

TSampleShape をコンポーネントパレットの［Samples］ページに登録する

作成したユニットのコードは次のようになります。

unit Shapes;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms;

type

TSampleShape = class(TGraphicControl)

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponent('Samples', [TSampleShape]);

end;

end.


Publishing inherited properties
Publishing inherited properties1118003

Section topics 	参照

コンポーネント型を派生させたら，次に，上位コンポーネントクラスの protected 部で宣言されているプロパティとイベントのうち，どれを新しいコンポーネントに公開するかを決定します。すでに TGraphicControl で，コンポーネントがコントロールとして機能するために必要なすべてのプロパティはパブリッシュに設定されているので，開発者が自分でパブリッシュに設定するのは，マウスイベントに応答してドラッグアンドドロップを処理する機能だけです。

継承プロパティと継承イベントをパブリッシュに設定する方法についての詳細は，「継承プロパティの公開」と「イベントの公開」を参照してください。どちらの場合も，クラス宣言の published 部でプロパティ名だけを再宣言します。

この図形コントロールの場合には，3 つのマウスイベント，3 つのドラッグアンドドロップイベント，2 つのドラッグアンドドロッププロパティをパブリッシュに設定します。この様子を次に示します。

type

TSampleShape = class(TGraphicControl)

published

property DragCursor; { ドラッグアンドドロッププロパティ }

property DragMode;

property OnDragDrop; { ドラッグアンドドロップイベント }

property OnDragOver;

property OnEndDrag;

property OnMouseDown; { マウスイベント }

property OnMouseMove;

property OnMouseUp;

end;

これで，マウスとドラッグアンドドロップに関する機能をユーザーに公開しました。


Adding graphic capabilities
Adding graphic capabilities1118004

Section topics 	参照

グラフィックコンポーネントを宣言して，公開するすべての継承プロパティをパブリッシュに設定したら，次はグラフィック機能を追加します。このグラフィック機能が，開発するコンポーネントを特徴付けます。

1.	描画対象を決定する

2.	コンポーネントイメージを描画する

また，この図形コントロールにはいくつかのプロパティを追加します。このプロパティによって，アプリケーション開発者が設計時に図形の外観をカスタマイズできるようになります。


Determining what to draw
Determining what to draw1118005

Section topics 	参照

グラフィックコントロールは，ユーザー入力などの動的な条件によって，外観を変更します。常に同一の画像を表示するものであればコンポーネントを作る必要はありません。静的な画像を表示するにはイメージコンポーネントに読み込ませてください。

一般にグラフィックコントロールの外観は，プロパティ値の組み合わせによって決まります。たとえばゲージコントロールには，形状を表すプロパティ，方向を表すプロパティ，進捗状況をグラフィックだけでなく数値でも示すかどうかを決定するプロパティなどがあります。同様に，図形コントロールには描画する図形の種類を決定するプロパティがあります。

コントロールに描画する図形を決定するプロパティ Shape を追加する場合は，以下の作業が必要です。

1.	プロパティ型の宣言

2.	プロパティの宣言

3.	メソッドの実現

プロパティを作成する方法についての詳細は「プロパティの作成」を参照してください。

Declaring the property type1118006

ユーザー定義のプロパティ型を使用する場合は，そのプロパティを含むクラスを宣言する前に，その型の宣言を行っておきます。ユーザー定義のプロパティ型で最も多く使われるのは列挙型です。

図形コントロールの場合は，コントロールが描画できる図形の種類を示すために，列挙型を定義します。

次の型宣言を，図形コントロールクラスの宣言よりも前に記述します。

type

TSampleShapeType = (sstRectangle, sstSquare, sstRoundRect, sstRoundSquare,

sstEllipse, sstCircle);

TSampleShape = class(TGraphicControl)	{ 元からある文 }

これで，この型のプロパティをクラスで宣言できるようになりました。

Declaring the property1118007

通常，プロパティを宣言する場合は，そのプロパティのデータを格納するプライベートなフィールドを宣言し，またそのプロパティ値の読み出しと書き込みのためのメソッドを指定します。プロパティ値の読み出しでは，メソッドを使用せず，データが格納されているフィールドをそのまま指定することもあります。

この図形コントロールの場合，現在の図形を格納するフィールドを宣言し，次にプロパティを宣言します。プロパティはメソッド呼び出しによってフィールドの読み出しや書き込みを行います。

次の宣言を TSampleShape に記述します。

type

TSampleShape = class(TGraphicControl)

private

FShape: TSampleShapeType;	{ プロパティ値を格納するフィールド }

procedure SetShape(Value: TSampleShapeType);

published

property Shape: TSampleShapeType read FShape write SetShape;

end;

後は，SetShape を実現するだけです。

Writing the implementation method1118008

プロパティ定義の read 部と write 部で，プロパティデータの操作方法として，直接アクセスではなくメソッドを指定した場合には，そのメソッドを実装する必要があります。

次のように，ユニットの実現部に SetShape メソッドの実装を記述します。

procedure TSampleShape.SetShape(Value: TSampleShapeType);

begin

if FShape <> Value then	{ 変更されていない場合は無視 }

begin

FShape := Value; { 新しい値を格納 }

Invalidate; { 新しい図形の再描画 }

end;

end;


Overriding the constructor and destructor
Overriding the constructor and destructor1118009

Section topics 	参照

コンポーネントのプロパティのデフォルト値を変更し，所有クラスを初期化するには，継承コンストラクタと継承デストラクタをオーバーライドしなければなりません。このとき，新しいコンストラクタやデストラクタから必ず継承メソッドを呼び出します。

Changing default property values1118010

グラフィックコントロールのデフォルトのサイズはやや小さいので，幅と高さをコンストラクタで変更します。プロパティのデフォルト値を変更する方法についての詳細は「既存のコンポーネントの変更」を参照してください。

このサンプルでは，図形コントロールを 1 辺が 65 ピクセルの正方形に設定します。

1.	コンポーネントクラスの宣言でコンストラクタをオーバーライドします。

type

TSampleShape = class(TGraphicControl)

public { コンストラクタは常にパブリック }

constructor Create(AOwner: TComponent); override {override 指令が必要 }

end;

2.	Height プロパティと Width プロパティを新しいデフォルト値で再宣言します。

type

TSampleShape = class(TGraphicControl)

...

published

property Height default 65;

property Width default 65;

end;

3.	ユニットの実現部に新しいコンストラクタを記述します。

constructor TSampleShape.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 常に継承コンストラクタを呼び出す }

Width := 65;

Height := 65;

end;


Publishing the pen and brush
Publishing the pen and brush1118011

Section topics 	参照

デフォルトでは，キャンバスは黒色の細いペンと白色のソリッドブラシを使用します。開発者がペンとブラシを変更できるようにするには，開発者が設計時に操作できるクラスを用意し，描画するときにそのクラスをキャンバスにコピーします。ペンやブラシのようなクラスは所有クラスと呼ばれます。コンポーネントによって所有され，コンポーネントによって作成，廃棄されるからです。

所有クラスを管理する場合は，以下の作業が必要です。

1.	クラスフィールドの宣言

2.	アクセスプロパティの宣言

3.	所有クラスの初期化

Declaring the class fields1118012

コンポーネントには，それぞれの所有クラスのためにクラスフィールドが必要です。コンポーネントはそのクラスフィールドによって所有オブジェクトに対するポインタを保持し，コンポーネント自身を廃棄する前に所有クラスを廃棄します。一般に，コンポーネントは所有オブジェクトをコンストラクタで初期化し，デストラクタで廃棄します。

所有オブジェクト用のフィールドは，ほとんどの場合プライベートに宣言されます。アプリケーションやほかのコンポーネントがその所有オブジェクトにアクセスする場合は，それを可能にするためにパブリッシュプロパティまたはパブリックプロパティを宣言します。

次のようにして，ペンとブラシのためのフィールドを図形コントロールに追加します。

type

TSampleShape = class(TGraphicControl)

private { ほとんどの場合，フィールドはプライベート }

FPen: TPen; { ペンオブジェクト用のフィールド }

FBrush: TBrush; { ブラシオブジェクト用のフィールド }

...

end;

Declaring the access properties1118013

コンポーネントの所有オブジェクトへのアクセスを用意するには，オブジェクト型のプロパティを宣言します。開発者は，設計時でも実行時でも，そのプロパティをとおして所有オブジェクトにアクセスします。一般に，プロパティの read 部ではクラスのフィールドを単純に参照し，write 部では所有オブジェクトの変更にコンポーネントが反応できるようにメソッドを呼び出します。

図形コントロールに，ペンフィールドとブラシフィールドへのアクセスを提供するプロパティを追加します。また，ペンやブラシの変更に反応するためのメソッドを宣言します。

type

TSampleShape = class(TGraphicControl)

...

private	{ この 2 つのメソッドはプライベートにする }

procedure SetBrush(Value: TBrush);

procedure SetPen(Value: TPen);

published	{ 設計時に操作可能にする }

property Brush: TBrush read FBrush write SetBrush;

property Pen: TPen read FPen write SetPen;

end;

次に，ユニットの実現部に SetBrush メソッドと SetPen メソッドを記述します。

procedure TSampleShape.SetBrush(Value: TBrush);

begin

FBrush.Assign(Value); { 既存のブラシをパラメータで置換 }

end;

procedure TSampleShape.SetPen(Value: TPen);

begin

FPen.Assign(Value); { 既存のペンをパラメータで置換 }

end;

Initializing owned classes1118014

コンポーネントにクラスを追加した場合には，そのコンポーネントのコンストラクタにクラスを初期化させ，ユーザーが実行時にそれらのオブジェクトと対話できるようにします。同様に，コンポーネントのデストラクタにはコンポーネント自身を廃棄する前に，所有オブジェクトを廃棄させるようにします。

図形コントロールにペンとブラシを追加したので，図形コントロールのコンストラクタでそれを初期化し，また図形コントロールのデストラクタでそれを廃棄します。この様子を次に示します。

1.	図形コントロールのコンストラクタでペンとブラシを作成します。

constructor TSampleShape.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 常に継承コンストラクタを呼び出す }

Width := 65;

Height := 65;

FPen := TPen.Create; { ペンを構築 }

FBrush := TBrush.Create; { ブラシを構築 }

end;

2.	コンポーネントオブジェクトの宣言でデストラクタをオーバーライドします。

type

TSampleShape = class(TGraphicControl)

public { デストラクタは常にパブリック}

constructor Create(AOwner: TComponent); override;

destructor Destroy; override; { override 指令を忘れないように }

end;

3.	ユニットの実現部に新しいデストラクタを記述します。

destructor TSampleShape.Destroy;

begin

FPen.Free; { ペンオブジェクトを廃棄 }

FBrush.Free; { ブラシオブジェクトを廃棄 }

inherited Destroy; { 常に継承デストラクタも呼び出す }

end;

Setting owned classes' properties1118015

最後に，ペンとブラシが変更された際に図形コントロールが自分自身を再描画するようにします。ペンクラスとブラシクラスには OnChange イベントがあるので，図形コントロールでメソッドを作成し，両方の OnChange イベントがそのメソッドを指すようにします。

図形コントロールにメソッドを記述します。また，コンポーネントのコンストラクタで，ペンとブラシの OnChange イベントがその新しいメソッドを指すように設定します。この様子を次に示します。

type

TSampleShape = class(TGraphicControl)

published

procedure StyleChanged(Sender: TObject);

end;

...

implementation

...

constructor TSampleShape.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 常に継承コンストラクタを呼び出す }

Width := 65;

Height := 65;

FPen := TPen.Create; { ペンを構築 }

FPen.OnChange := StyleChanged; { OnChange イベントにメソッドを割り当てる }

FBrush := TBrush.Create; { ブラシを構築 }

FBrush.OnChange := StyleChanged; { OnChange イベントにメソッドを割り当てる }

end;

procedure TSampleShape.StyleChanged(Sender: TObject);

begin

Invalidate(True); { コンポーネントを消去して再ペイント }

end;

これで，ペンまたはブラシを変更するとコンポーネントが再描画されるようになりました。


Drawing the component image
Drawing the component image1118016

Section topics 	参照

グラフィックコントロールの本質は，画面にイメージを描画する方法で決まります。コントロールにイメージを描画するには，TGraphicControl 抽象型で定義されている Paint というメソッドをオーバーライドします。

図形コントロールの Paint メソッドは，以下の条件を満たすように作成します。

選択されたペンとブラシを使用する

選択された図形を使用する

正方形と円の場合は幅と高さを同じにする

Paint メソッドをオーバーライドする手順は次のとおりです。

1.	コンポーネントの宣言に Paint を追加します。

2.	Paint メソッドをユニットの実現部に記述します。

この図形コントロールの場合，クラスの宣言で次のようにメソッドを宣言します。

type

TSampleShape = class(TGraphicControl)

...

protected

procedure Paint; override;

...

end;

次に，ユニットの実現部にメソッドを記述します。

procedure TSampleShape.Paint;

begin

with Canvas do

begin

Pen := FPen; { コンポーネントのペンをコピー }

Brush := FBrush; { コンポーネントのブラシをコピー }

case FShape of

sstRectangle, sstSquare:

Rectangle(0, 0, Width, Height); { 長方形と正方形を描画 }

sstRoundRect, sstRoundSquare:

RoundRect(0, 0, Width, Height, Width div 4, Height div 4); { 角の丸い長方形を描画 }

sstCircle, sstEllipse:

Ellipse(0, 0, Width, Height); { 楕円を描画 }

end;

end;

end;

コントロールがイメージを更新する必要があるときは常に Paint が呼び出されます。コントロールが最初に表示される場合や，コントロールの前面に表示されているウィンドウが移動した場合は，Windows がそのコントロールに対して描画を指示します。Invalidate を呼び出して再描画を強制することもできます。これは StyleChanged メソッドでも行っている方法です。


Refining the shape drawing
Refining the shape drawing1118017

Section topics 	参照

標準の図形コントロールは，長方形や楕円だけでなく正方形や円を描画できますが，このサンプルにはまだその機能がありません。正方形や円を描画する場合は，図形のもっとも短い辺を見つけ，図形を中央に位置付けるコードを記述する必要があります。

正方形と円を正しく描画できるように改良した Paint を次に示します。

procedure TSampleShape.Paint;

var

X, Y, W, H, S: Integer;

begin

with Canvas do

begin

Pen := FPen; { コンポーネントのペンをコピー }

Brush := FBrush; { コンポーネントのブラシをコピー }

W := Width; { コンポーネントの幅 }

H := Height; { コンポーネントの高さ }

if W < H then S := W else S := H; { 正方形と円のために短い辺を取得 }

case FShape of { 高さ，幅，位置を調整 }

sstRectangle, sstRoundRect, sstEllipse:

begin

X := 0; { 原点は図形の最上部左端 }

Y := 0;

end;

sstSquare, sstRoundSquare, sstCircle:

begin

X := (W - S) div 2; { 水平方向の中心を決定 }

Y := (H - S) div 2; { 垂直方向の中心を決定 }

W := S; { 幅を短い辺に合わせる }

H := S; { 高さを短い辺に合わせる }

end;

end;

case FShape of

sstRectangle, sstSquare:

Rectangle(X, Y, X + W, Y + H); { 長方形や正方形を描画 }

sstRoundRect, sstRoundSquare:

RoundRect(X, Y, X + W, Y + H, S div 4, S div 4); { 角の丸い長方形を描画 }

sstCircle, sstEllipse:

Ellipse(X, Y, X + W, Y + H); { 楕円を描画 }

end;

end;

end;


See also1118018

既存のコンポーネントの変更

TShape

TGraphicControl


Customizing a grid
Customizing a grid1100001

Section topics 	参照

Delphi には，コンポーネントをカスタマイズするときに土台として使用できる抽象コンポーネントがあります。このうちよく使用されるのはグリッドとリストボックスです。この章では， グリッドコンポーネント TCustomGrid を元にして，1か月分の表示ができる小さなカレンダ－を作成します。

このカレンダーを作成する場合は，以下の作業が必要です。

コンポーネントの作成と登録

継承プロパティの公開

初期値の変更

セルのサイズ変更

セルの内容の表示

月と年の変更

日付（日）の変更

作成するカレンダーコンポーネントは，コンポーネントパレットの［Samples］ページにある TCalendar に似ています。


Creating and registering the component
Creating and registering the component1100002

Section topics 	参照

コンポーネントの作成は常に同じ方法（ユニット）で開始します。ユニットを作成し，コンポーネントクラスを派生させて登録し，コンパイルしてコンポーネントパレットにインストールします。

このサンプルでも同じ手順でコンポーネントを作成します。このコンポーネントに固有の点は以下のとおりです。

コンポーネントユニットの名前は CalSamp とする

TCustomGrid から TSampleCalendar という新しいコンポーネント型を派生させる

TSampleCalendar をコンポーネントパレットの［Samples］ページに登録する

作成したユニットのコードは次のようになります。

unit CalSamp;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Grids;

type

TSampleCalendar = class(TCustomGrid)

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents('Samples', [TSampleCalendar]);

end;

end.

このカレンダーコンポーネントをインストールすると，コンポーネントは［Samples］ページに表示されます。最も基本的なコントロールプロパティしか使用できません。次の節では，このカレンダーのユーザーが，より特化したプロパティを使用できるようにします。

メモ	コンパイルしたばかりのサンプルのカレンダーコンポーネントをインストールすることはできますが，まだフォームに配置することはできません。TCustomGrid コンポーネントには，インスタンスオブジェクトを作成するために再宣言しなければならない抽象メソッド DrawCell を持っています。DrawCell メソッドのオーバーライドについての詳細は，｢セルの内容の表示」で後述します。


Publishing inherited properties
Publishing inherited properties1100003

Section topics 	参照

抽象グリッドコンポーネント TCustomGrid には，多くのプロテクトプロパティがあります。その中から，ユーザーに公開するカレンダーコントロールのプロパティを選択します。

コンポーネントのユーザーに継承したプロテクトプロパティを公開するには，コンポーネント宣言の published 部でそのプロパティを再宣言します。

このカレンダーコントロールでは，次に示すようにいくつかのプロパティとイベントをパブリッシュに設定します。

type

TSampleCalendar = class(TCustomGrid)

published

property Align; { プロパティをパブリッシュに設定 }

property BorderStyle;

property Color;

property Ctl3D;

property Font;

property GridLineWidth;

property ParentColor;

property ParentFont;

property OnClick; { イベントをパブリッシュに設定 }

property OnDblClick;

property OnDragDrop;

property OnDragOver;

property OnEndDrag;

property OnKeyDown;

property OnKeyPress;

property OnKeyUp;

end;

ほかにも，描画されるグリッド線を選択する Options プロパティなど多くのプロパティがあります。そのようなプロパティもパブリッシュに設定できますが，カレンダーではその必要はありません。

ここでコンポーネントパレットを再構築すれば，変更したカレンダーコンポーネントを使用できます。変更後のカレンダーには，最初よりも多くのプロパティとイベントがあります。次の節では独自の機能を新しく追加します。


Changing initial values
Changing initial values1100004

Section topics 	参照

カレンダーは基本的に，行と列の数が固定されているグリッドです（もっとも，常にすべての行に日付が表示されるとは限りません）。カレンダーは常に 1 週間を 7 日で表示するからです。そのため，グリッドのプロパティ ColCount と RowCountは，パブリッシュには設定してありません。ただし，1週間を7日にするためには，プロパティの初期値をそのように設定しなければなりません。

コンポーネントプロパティの初期値を変更するには，コンストラクタをオーバーライドして値を設定します。コンストラクタは仮想でなければなりません。

コンポーネントのオブジェクト宣言の public 部にコンストラクタの宣言を追加し，ユニットの実現部に新しいコンストラクタを記述します。新しいコンストラクタでは，最初の文で継承コンストラクタを呼び出します。

type

TSampleCalendar = class(TCustomGrid

public

constructor Create(AOwner: TComponent); override;

...

end;

...

constructor TSampleCalendar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 継承コンストラクタを呼び出す }

ColCount := 7; { 常に 1 週は 7 日 }

RowCount := 7; { 常に 6 週間＋見出し }

FixedCols := 0; { 見出しを付けない }

FixedRows := 1; { 1行の見出しに曜日を表示 }

ScrollBars := ssNone; { スクロールは使用しない }

Options := Options - [goRangeSelect] + [goDrawFocusSelected]; { 範囲選択は使用しない }

end;


Resizing the cells
Resizing the cells1100005

Section topics 	参照

ユーザーやアプリケーションがウィンドウやコントロールのサイズを変更した場合には，Windows はサイズ変更されたウィンドウやコントロールに対して WM_SIZE というメッセージを送り，ウィンドウやコントロールが新しいサイズでイメージを描画するために必要な情報を通知します。コンポーネント側では，このメッセージに応答して，すべてのセルがコントロールの境界内に収まるようにセルのサイズを変更します。WM_SIZE メッセージに応答するには，コンポーネントにメッセージ処理メソッドを追加します。

メッセージ処理メソッドを作成する方法についての詳細は，「新しいメッセージハンドラの作成」を参照してください。

このサンプルのカレンダーコントロールで WM_SIZE に応答するため，WMSize という名前のプロテクトメソッドを追加して WM_SIZE に結び付けます。このメソッドでは，すべてのセルが表示できるようにセルサイズを計算します。次にそのコードを示します。

type

TSampleCalendar = class(TCustomGrid)

protected

procedure WMSize(var Message: TWMSize); message WM_SIZE;

...

end;

...

procedure TSampleCalendar.WMSize(var Message: TWMSize);

var

GridLines: Integer; { 一時的なローカル変数 }

begin

GridLines := 6 * GridLineWidth; { 線の幅の合計を計算 }

DefaultColWidth := (Message.Width - GridLines) div 7; { 新しいデフォルトのセル幅を設定 }

DefaultRowHeight := (Message.Height - GridLines) div 7; { 同様にセルの高さも設定 }

end;


Filling in the cells
Filling in the cells1100006

Section topics 	参照

グリッドコントロールでは，各セルにそれぞれの内容があります。このカレンダーでは，各セルごとに表示する日付を計算します。ただし，セルによっては表示する日付がないこともあります。デフォルトでは，グリッドのセルの描画は DrawCell という仮想メソッドで行われます。

グリッドセルに内容を表示するには，DrawCell メソッドをオーバーライドします。

固定行にある見出しのセルは，簡単に表示できます。ランタイムライブラリに曜日の略称の配列があるので，カレンダーにはその配列を利用して各列の見出しセルに内容を表示します。この様子を次に示します。

type

TSampleCalendar = class(TCustomGrid)

protected

procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);

override;

end;

...

procedure TSampleCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect;

AState: TGridDrawState);

begin

if ARow = 0 then

Canvas.TextOut(ARect.Left, ARect.Top, ShortDayNames[ACol + 1]); { 見出しにランタイムライブラリの文字列で表示 }

end;


Tracking the date
Tracking the date1100007

Section topics 	参照

このカレンダーコントロールを実用的なものにするには，ユーザーやアプリケーションが年，月，日を設定できるようにしなければなりません。Delphi は日付と時間を TDateTime 型の変数に格納します。TDateTime は日付と時間をコード化した数値表現なので，プログラムで操作するには便利ですが，人間の使用には適していません。

そこで，TDateTime に日付をコード化して格納し，その値への実行時のアクセス方法を用意しますが，同時に Year，Month，Day の各プロパティも提供します。カレンダーコンポーネントのユーザーは，このプロパティを設計時に使用できます。

Storing the internal date1100008

カレンダーの日付を格納するために，日付を格納するプライベートなフィールドと，その日付をアクセスする実行時用のプロパティを用意します。

カレンダーで日付を内部的に格納するための手順は次のとおりです。

1.	日付を格納するフィールドをプライベートに宣言します。

type

TSampleCalendar = class(TCustomGrid)

private

FDate: TDateTime;

...

2.	その日付フィールドをコンストラクタで初期化します。

constructor TSampleCalendar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 元からある文 }

... { ここでほかの初期化を行う }

FDate := Date; { ランタイムライブラリから現在の日付を取得 }

end;

3.	コード化された日付にアクセスする実行時用のプロパティを宣言します。

日付を設定したときは，コントロールに表示されるイメージも更新しなければならないので，日付の設定はメソッドで行います。

type

TSampleCalendar = class(TCustomGrid)

private

procedure SetCalendarDate(Value: TDateTime);

public

property CalendarDate: TDateTime read FDate write SetCalendarDate;

...

procedure TSampleCalendar.SetCalendarDate(Value: TDateTime);

begin

FDate := Value; { 新しい日付を設定 }

Refresh; { イメージの表示を更新 }

end;

Accessing the day, month, and year1100009

コード化された数値はプログラムにとっては扱いやすいものですが，人間が操作しやすいのは年，月，日の個別の値です。そこで，コード化された日付の各要素へアクセスするためのプロパティを作成します。

日付の各要素（年，月，日）はすべて整数であり，またどの要素も設定や取得にはコード化された日付との変換が必要です。そこで，3 つのプロパティに共通の実装メソッドを指定して，コードの重複を回避します。つまり，要素を読み出すメソッドと要素を書き込むメソッドの 2 つのメソッドを記述するだけで，3 つのプロパティの取得と設定を実現します。

設計時に年，月，日へアクセスできるようにする手順は以下のとおりです。

1.	3 つのプロパティを宣言し，それぞれにユニークなインデックス番号を割り当てます。

type

TSampleCalendar = class(TCustomGrid)

public

property Day: Integer index 3 read GetDateElement write SetDateElement;

property Month: Integer index 2 read GetDateElement write SetDateElement;

property Year: Integer index 1 read GetDateElement write SetDateElement;

...

2.	実装メソッドを宣言して記述します。各インデックス値に対応する要素をアクセスします。

type

TSampleCalendar = class(TCustomGrid)

private

function GetDateElement(Index: Integer): Integer; { インデックス値をパラメータに渡す }

procedure SetDateElement(Index: Integer; Value: Integer);

...

function TSampleCalendar.GetDateElement(Index: Integer): Integer;

var

AYear, AMonth, ADay: Word;

begin

DecodeDate(FDate, AYear, AMonth, ADay); { コード化された日付から要素を抽出 }

case Index of

1: Result := AYear;

2: Result := AMonth;

3: Result := ADay;

else Result := -1;

end;

end;

procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);

var

AYear, AMonth, ADay: Word;

begin

if Value > 0 then	{ 要素は必ず正の値であること }

begin

DecodeDate(FDate, AYear, AMonth, ADay);	{ 現在の日付の要素を取得 }

case Index of	{ インデックス値に対応する要素を設定 }

1: AYear := Value;

2: AMonth := Value;

3: ADay := Value;

else Exit;

end;

FDate := EncodeDate(AYear, AMonth, ADay); { 変更された日付をコード化 }

Refresh; { カレンダーの表示を更新}

end;

end;

これで，カレンダーの年，月，日を設定できるようになりました。年，月，日の設定は，設計時にオブジェクトインスペクタを使用して行うか，実行時にコードで行います。セルに日付を描画するコードはまだ記述していませんが，必要なデータは揃いました。


Generating the day numbers
Generating the day numbers1100010

Section topics 	参照

カレンダーに日付を表示するには，いくつか考慮しなければならない点があります。1 か月の日数は，その月が何月かによって，またその年がうるう年かどうかによって変化します。また，年によって月が始まる曜日はまちまちです。

カレンダークラスにメソッドを 2 つ追加します。現在の年がうるう年かどうかを示す論理型関数と，現在の月の日数を返す整数型関数です。この 2 つのメソッドを記述し，宣言を TSampleCalendar のクラス宣言に追加します。

function TSampleCalendar.IsLeapYear: Boolean;

begin

Result := (Year mod 4 = 0)	{ 4 の倍数の年はうるう年 ... }

and ((Year mod 100 <> 0)	{ ...100 の倍数の年は除く ... }

or (Year mod 400 = 0));	{ ...400 の倍数ならうるう年 }

end;

function TSampleCalendar.DaysThisMonth: Integer;

const

DaysPerMonth: array[1..12] of Integer =

(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);	{ 通常の日数 }

begin

if FDate = 0 then Result := 0	{ 0 は無効な日付を示す }

else

begin

Result := DaysPerMonth[Month];	{ 普通は日数をそのまま返す }

if (Month = 2) and IsLeapYear then Inc(Result);	{ うるう年の 2 月は 1 日加算 }

end;

end;

日付が格納されていない場合は，DaysThisMonth 関数はゼロを返します。アプリケーションではこれを利用して無効な日付を示します。月の日数としてゼロが返された場合には，カレンダーを空白にして，その日付が無効であることを示します。

うるう年と月の日数についての情報を取得したら，次に各日付を表示するグリッド上の場所を計算します。この結果は，その月の最初の曜日によって決まります。

各日付を表示するセルは，年と月によって異なります。そこで，年と月の値を常に反映させたオフセット値を保持し，必要なときにその値を参照するようにします。実際には，オフセット値をクラスフィールドに格納しておいて，日付が変更されるたびに再計算します。

日付を適切なセルに表示する手順は次のとおりです。

1.	オフセットフィールドと，このフィールドの値を計算するメソッドをオブジェクトに追加します。

type

TSampleCalendar = class(TCustomGrid)

private

FMonthOffset: Integer; { オフセット値の格納場所 }

...

protected

procedure UpdateCalendar; virtual; { オフセット値にアクセスするプロパティ }

end;

...

procedure TSampleCalendar.UpdateCalendar;

var

AYear, AMonth, ADay: Word;

FirstDate: TDateTime; { その月の最初の日付 }

begin

if FDate <> 0 then { 日付が有効な場合のみオフセット値を計算 }

begin

DecodeDate(FDate, AYear, AMonth, ADay); { 日付の要素を取得 }

FirstDate := EncodeDate(AYear, AMonth, 1); { 最初の日付 }

FMonthOffset := 2 - DayOfWeek(FirstDate); { グリッド上のオフセット値を計算 }

end;

Refresh; { 常にコントロールを再描画 }

end;

2.	コンストラクタにコードを追加します。また，日付を変更したときに UpdateCalendar を呼び出す SetCalendarDate メソッドと SetDateElement メソッドを記述します。

constructor TSampleCalendar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 元からある文 }

... { ここでほかの初期化を行う }

UpdateCalendar; { 適切なオフセット値を設定 }

end;

procedure TSampleCalendar.SetCalendarDate(Value: TDateTime);

begin

FDate := Value; { 元からある文 }

UpdateCalendar; { 以前はここで Refresh を呼び出していた }

end;

procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);

begin

...

FDate := EncodeDate(AYear, AMonth, ADay); { 変更された日付をコード化 }

UpdateCalendar; { 以前はここで Refresh を呼び出していた }

end;

end;

3.	行と列のセル座標を渡すと日付（日の数値）を返すメソッドをカレンダーに追加します。

function TSampleCalendar.DayNum(ACol, ARow: Integer): Integer;

begin

Result := FMonthOffset + ACol + (ARow - 1) * 7; { このセルの日付（日の数値）を計算 }

if (Result < 1) or (Result > DaysThisMonth) then Result := -1; { 無効な場合は -1 を返す }

end;

また，コンポーネントの型宣言にこの DayNum の宣言を追加します。

4.	これで，日付を表示する場所を計算できるようになりました。そこで DrawCell を改良して，日付を表示するようにします。

procedure TCalendar.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);

var

TheText: string;

TempDay: Integer;

begin

if ARow = 0 then { 見出し行ならば ...}

TheText := ShortDayNames[ACol + 1] { 表示するのは曜日の名称 }

else

begin

TheText := ''; { デフォルトは空白 }

TempDay := DayNum(ACol, ARow); { このセルに表示する数値を取得 }

if TempDay <> -1 then TheText := IntToStr(TempDay); { 有効な場合はその数値を使用 }

end;

with ARect, Canvas do

TextRect(ARect, Left + (Right - Left - TextWidth(TheText)) div 2,

Top + (Bottom - Top - TextHeight(TheText)) div 2, TheText);

end;

ここで，このカレンダーコンポーネントを再びインストールしてフォームに配置すると，現在の月が正しく表示されます。


Selecting the current day
Selecting the current day1100011

Section topics 	参照

カレンダーの各セルに日付が表示されるようになりました。そこで，現在の日付のセルが常に選択され，強調表示されるようにします。デフォルトでは，左上端のセルが選択されていますが，選択するセルは Row プロパティと Column プロパティで指定できます。常に適切なセルが選択されているようにするには，カレンダーを作成したときと，日付が変更されたときの両方の場合に 2 つのプロパティを設定します。

現在の日付のセルを選択するには，UpdateCalendar メソッドが Refresh を呼び出す前に Row と Column を設定します。

procedure TSampleCalendar.UpdateCalendar;

begin

if FDate <> 0 then

begin

... { FMonthOffset を設定する既存の文 }

Row := (ADay - FMonthOffset) div 7 + 1;

Col := (ADay - FMonthOffset) mod 7;

end;

Refresh; { 元からある文 }

end;

この手続きでは，コード化された日付から抽出しておいた ADay 変数を再利用しています。


Navigating months and years
Navigating months and years1100012

Section topics 	参照

プロパティによるコンポーネントの操作は便利なものです。プロパティは設計時にも操作できます。しかし，一般的で自然な操作についてはメソッドを用意した方がよい場合もあります。メソッドを使用すれば，複数のプロパティを一度に操作することもできます。そのような例の 1 つが，カレンダーの「翌月」機能です。月と年を変更するのは単純な処理ですが，コンポーネントを使用する開発者にとっては便利な機能です。

一般的な操作をメソッドにカプセル化する方法の唯一の欠点は，メソッドは実行時にしか処理できない点です。しかし，一般にそのような操作を繰り返すのは繁雑なことであり，通常，設計時に実行することはありません。

このカレンダーでは以下の 4 つのメソッドを定義して，直後と直前の月または年へ移動できるようにします。

procedure TCalendar.NextMonth;

begin

if Month < 12 then { 12 月でなかった場合には ... }

Month := succ(Month) { ... 単純に月をインクリメント }

else

begin

Year := Year + 1; { そうでない場合には，翌年の ... }

Month := 1; { ...1 月にする }

end;

end;

procedure TCalendar.PrevMonth;

begin

if Month > 1 then { 1月でなかった場合には ... }

Month := pred(Month) { ... 単純に月をデクリメント }

else

begin

Year := Year - 1; { そうでない場合には，前年の ... }

Month := 12; { ...12 月にする }

end;

end;

procedure TCalendar.NextYear;

begin

Year := Year + 1; { 年をインクリメント }

end;

procedure TCalendar.PrevYear;

begin

Year := Year - 1; { 年をデクリメント }

end;

この 4 つのメソッドの宣言を必ずクラスの宣言に追加してください。

これで，このカレンダーコンポーネントを使用するアプリケーションから，月や年を簡単に変更できます。


Navigating days
Navigating days1100013

Section topics 	参照

特定の月において日付を変更する方法としては，矢印キーを使用する方法と，マウスのクリックに応答する方法が考えられます。標準グリッドコンポーネントでは，この 2 つの操作は両方ともクリックとして処理されます。つまり，矢印キーを押す操作は，隣のセルをクリックする操作として扱われます。


Moving the selection
Moving the selection1100014

Section topics 	参照

矢印キーまたはマウスクリックに応答して，選択されたセルを変更する機能は，グリッドから継承されています。しかし，選択された日付を変更するには，このデフォルトの機能を変更します。

カレンダー内の移動を処理するには，グリッドの Click メソッドをオーバーライドします。

Click のようなユーザーとやり取りするメソッドをオーバーライドする場合は，通常，標準の機能が失われないように継承メソッドの呼び出しを行います。

カレンダーグリッド用にオーバーライドされた Click メソッドの例を次に示します。なお，TSampleCalendar で Click メソッドを override 指令を付けて宣言しておきます。

procedure TSampleCalendar.Click;

var

TempDay: Integer;

begin

inherited Click; { 継承メソッドを呼び出す }

TempDay := DayNum(Col, Row); { クリックされたセルの日付を取得 }

if TempDay <> -1 then Day := TempDay; { 有効な場合は日付を変更 }

end;


Providing an OnChange event
Providing an OnChange event1100015

Section topics 	参照

カレンダーのユーザーが日付を変更できるようになったので，次はアプリケーションがその変更に応答する手段を用意します。

TSampleCalendar に OnChange イベントを追加します。

1.	イベント，イベントを格納するフィールド，イベントを呼び出す動的メソッドを宣言します。

type

TSampleCalendar = class(TCustomGrid)

private

FOnChange: TNotifyEvent;

protected

procedure Change; dynamic;

...

published

property OnChange: TNotifyEvent read FOnChange write FOnChange;

...

2.	Change メソッドを記述します。

procedure TSampleCalendar.Change;

begin

if Assigned(FOnChange) then FOnChange(Self);

end;

3.	SetCalendarDate メソッドと SetDateElement メソッドの最後に，Change を呼び出す文を追加します。

procedure TSampleCalendar.SetCalendarDate(Value: TDateTime);

begin

FDate := Value;

UpdateCalendar;

Change; { 新しい文 }

end;

procedure TSampleCalendar.SetDateElement(Index: Integer; Value: Integer);

begin

... { 要素の値を設定する文 }

FDate := EncodeDate(AYear, AMonth, ADay);

UpdateCalendar;

Change; { 新しい文 }

end;

end;

カレンダーコンポーネントを使用するアプリケーションは，OnChange イベントにハンドラを結び付ければ，コンポーネントの日付の変更に応答できます。


Excluding blank cells
Excluding blank cells1100016

Section topics 	参照

カレンダーの書き込みでは，空白のセルも選択できますが，その場合は日付は変更されません。そこで，空白のセルは選択できないようにします。

セルの選択を制御するには，グリッドの SelectCell メソッドをオーバーライドします。

SelectCell 関数は，列と行をパラメータとして受け取り，指定のセルが選択可能かどうかを論理値で返します。

SelectCell をオーバーライドして，セルに有効な日付が入っていない場合は False を返すようにします。その例を次に示します。

function TSampleCalendar.SelectCell(ACol, ARow: Longint): Boolean;

begin

if DayNum(ACol, ARow) = -1 then Result := False { -1 は無効な日付を示す }

else Result := inherited SelectCell(ACol, ARow); { そうでなければ値を継承 }

end;

ユーザーが空白のセルをクリックしたり，矢印キーによって空白のセルに移動しようとした場合は，カレンダーコンポーネントは現状を維持し，選択されているセルを変更しません。


See also1100017

TCustomGrid

TCalendar

新しいメッセージハンドラの作成


Making a control data-aware
Making a control data-aware1101001

Section topics 	参照

データベースとの接続を行う場合，データベース対応のコントロールが用意されていると便利です。データベース対応のコントロールは，データベースの特定の部分との間にリンクを確立します。Delphi には，データベース対応のラベル，編集ボックス，リストボックス，コンボボックス，参照コントロール，グリッドが用意されています。また，独自にデータベース対応のコントロールを作成することもできます。

データベースへの対応にはいくつかのレベルがあります。最も単純なレベルは読み出し専用のデータベース対応です。このレベルでは，データ参照によってデータベースの現在の状態を反映できます。少し複雑なレベルとして，編集可能なデータベース対応があります。このレベルでは，ユーザーはコントロールを操作してデータ編集を行うことができます。これとは別に，単一の項目にリンクするだけの場合もあれば，複数のレコードを制御する場合もあります。

ここでは，最も単純な例として，データセット内の単一の項目にリンクした読み出し専用コントロールを作成します。ここで使用するコントロールは，「グリッドのカスタマイズ」で作成されるカレンダー TSampleCalendar です。コンポーネントパレットの［Samples］ページにある標準カレンダー TCalendar も使用することができます。

そのあと，新しいデータブラウズコントロールとデータ編集コントロールの作成のしかたを説明します。


Creating a data-browsing control
Creating a data-browsing control1101002

Section topics 	参照

データベース対応のカレンダーコントロールの作成には，読み出し専用コントロールの場合も，ユーザーがデータセット内の基礎になるデータを変更できるコントロールの場合も，以下の作業が必要です。

コンポーネントの作成と登録

データリンクの追加

データの変更の反映


Creating and registering the component
Creating and registering the component1101003

Section topics 	参照

コンポーネントの作成は常に同じ方法で開始します。ユニットを作成し，コンポーネントクラスを派生させて登録し，コンパイルしてコンポーネントパレットにインストールします。

このサンプルでは，一般的な手順でコンポーネントを作成します。コンポーネントに固有の点は以下のとおりです。

コンポーネントユニットの名前は DBCal とする

TSampleCalendar から TDBCalendar という新しいコンポーネントクラスを派生させる。TDBCalendar をコンポーネントパレットの［Samples］ページに登録する

例

作成したユニットのコードは次のようになります。

unit DBCal;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,

Forms, Grids, Calendar;

type

TDBCalendar = class(TSampleCalendar)

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents('Samples', [TDBCalendar]);

end;

end.

これから，この新しいカレンダーをデータブラウザに変更していきます。


Making the control read-only
Making the control read-only1101004

Section topics 	参照

このカレンダーはデータに対して読み出し専用なので，コントロール自体を読み出し専用にします。データベースは変更されないにもかかわらず，コントロールのデータだけが変更できるようになっているとユーザーが混乱するからです。

カレンダーを読み出し専用にする場合は，以下の作業が必要です。

ReadOnly プロパティの追加

必要な更新の許可

TSampleCalendar ではなく，コンポーネントパレットの［Samples］ページにある TCalendar を基にしてコントロールを作成する場合は，すでに ReadOnly プロパティがあるので，このステップは飛ばしてください。

Adding the ReadOnly property1101005

ReadOnly プロパティを追加すれば，設計時にコントロールを読み出し専用に設定できます。プロパティを True に設定すると，コントロールのすべてのセルが選択不可になります。

ReadOnly プロパティを追加するには，

1.	プロパティ宣言と，プロパティの値を格納するための private フィールドを追加します。ただし，TSampleCalendar ではなく TCalendar を基準にこのカレンダーを作成している場合は，すでに ReadOnly プロパティが定義されているので，ここで宣言する必要はありません。

type

TDBCalendar = class(TSampleCalendar)

private

FReadOnly: Boolean; { 内部記憶用のフィールド }

public

constructor Create(AOwner: TComponent); override; { 必ずオーバーライドしてデフォルト値を設定 }

published

property ReadOnly: Boolean read FReadOnly write FReadOnly default True;

end;

...

constructor TDBCalendar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 常に継承コンストラクタを呼び出す }

FReadOnly := True; { デフォルト値を設定 }

end;

2.	SelectCell メソッドをオーバーライドして，コントロールが読み出し専用になっている場合には選択を禁止します。SelectCell については「空白セルの除外」を参照してください。

function TDBCalendar.SelectCell(ACol, ARow: Longint): Boolean;

begin

if FReadOnly then Result := False { 読み出し専用の場合には選択不可 }

else Result := inherited SelectCell(ACol, ARow); { そうでなければ継承メソッドを呼び出す }

end;

また，TDBCalendar の型宣言に SelectCell を宣言し，override 指令を付加します。

これで，コントロールはクリックとキー入力を無視するようになりました。日付を変更した場合も選択セルが変更されません。

Allowing needed updates1101006

この読み出し専用カレンダーでは，Row プロパティと Col プロパティの設定など，あらゆる種類の変更は SelectCell メソッドをとおして行われます。UpdateCalendar メソッドは日付が変更されるたびに Row プロパティと Col プロパティを設定しようとしますが，SelectCell メソッドが変更を禁止します。そのため，日付が変更されても選択されているセルは変わりません。

そこで，カレンダーに内部的な論理フラグを追加し，このフラグが True に設定されている場合には変更が許可されるようにします。この様子を次に示します。

type

TDBCalendar = class(TSampleCalendar)

private

FUpdating: Boolean; { 内部使用のプライベートなフラグ }

protected

function SelectCell(ACol, ARow: Longint): Boolean; override;

public

procedure UpdateCalendar; override; { override 指令が必要 }

end;

...

function TDBCalendar.SelectCell(ACol, ARow: Longint): Boolean;

begin

if (not FUpdating) and FReadOnly then Result := False { 日付更新時は選択を許可 }

else Result := inherited SelectCell(ACol, ARow); { 継承メソッドを呼び出す }

end;

procedure TDBCalendar.UpdateCalendar;

begin

FUpdating := True; { 更新を許可するようにフラグを設定 }

try

inherited UpdateCalendar; { 通常のとおりに更新 }

finally

FUpdating := False; { 常にフラグをクリア }

end;

end;

依然としてユーザーの変更は禁止されていますが，日付プロパティの変更が適切に反映されるようになりました。これで，読み出し専用カレンダーが完成しました。次の節ではデータ参照機能を追加します。


Adding the data link
Adding the data link1101007

Section topics 	参照

コントロールとデータベースとの接続は，データリンクと呼ばれるクラスによって扱われます。コントロールをデータベースの単一の項目と接続するデータリンククラスは TFieldDataLink です。このほか，テーブル全体を扱うデータリンククラスもあります。

データベース対応のコントロールはデータリンククラスを所有します。つまり，コントロールは所有するデータリンクの構築と廃棄を行います。

所有クラスとしてデータリンクを確立する手順は次のとおりです。

1.	クラスフィールドを宣言します。

2.	アクセスプロパティを宣言します。

3.	データリンクを初期化します。

Declaring the class field1101008

「クラスフィールドの宣言」で説明したように，コンポーネントの所有クラスにはフィールドが必要です。このサンプルでは，データリンク用に TFieldDataLink 型のフィールドを使用します。

次のように，データリンク用のフィールドをカレンダーで宣言します。

type

TDBCalendar = class(TSampleCalendar)

private

FDataLink: TFieldDataLink;

...

end;

なお，このコンポーネントのユニットの uses 節に，DB と DBctrls を追加してください。

Declaring the access properties1101009

すべてのデータベース対応コントロールには DataSource プロパティがあります。このプロパティは，アプリケーションのどのデータソースクラスがコントロールにデータを供給するかを指定します。また，単一の項目にアクセスするコントロールには，データソースの項目を指定する DataField プロパティも必要です。

所有クラス用のアクセスプロパティは，所有オブジェクト自体へのアクセスを提供していました。これに対して，DataSource や DataField は所有クラスの特定のプロパティへのアクセスを提供します。これによって，コントロールとそのデータリンクは，同じデータソースとフィールド項目を共有できます。

DataSource プロパティ，DataField プロパティ，およびそれらの実装メソッドを宣言します。メソッドは，データリンククラスのプロパティをアクセスします。

例

type

TDBCalendar = class(TSampleCalendar)

private { 実装メソッドはプライベート }

...

function GetDataField: string; { データ項目名を返す }

function GetDataSource: TDataSource; { データソースに対する参照を返す }

procedure SetDataField(const Value: string); { データ項目名を指定する }

procedure SetDataSource(Value: TDataSource); { 新しいデータソースを指定する }

published	{ プロパティを設計時に操作できるようにする }

property DataField: string read GetDataField write SetDataField;

property DataSource: TDataSource read GetDataSource write SetDataSource;

end;

...

function TDBCalendar.GetDataField: string;

begin

Result := FDataLink.FieldName;

end;

function TDBCalendar.GetDataSource: TDataSource;

begin

Result := FDataLink.DataSource;

end;

procedure TDBCalendar.SetDataField(const Value: string);

begin

FDataLink.FieldName := Value;

end;

procedure TDBCalendar.SetDataSource(Value: TDataSource);

begin

FDataLink.DataSource := Value;

end;

Initializing the data link1101010

データベース対応のコントロールは，その存在の全期間をとおして，データリンクへのアクセスを必要とします。そこで，コントロールのコンストラクタでデータリンクオブジェクトを作成し，コントロールのデストラクタでデータリンクオブジェクトを廃棄します。

カレンダーの Create メソッドと Destroy メソッドをオーバーライドして，データリンクの作成と廃棄を行います。

type

TDBCalendar = class(TSampleCalendar)

public { コンストラクタとデストラクタは常にパブリック }

constructor Create(AOwner: TComponent); override;

destructor Destroy; override;

...

end;

...

constructor TDBCalendar.Create(AOwner: TComponent);

begin

FDataLink := TFieldDataLink.Create; { データリンクオブジェクトを作成 }

inherited Create(AOwner); { 常に最初に継承コンストラクタを呼び出す }

FReadOnly := True; { この文は前からこの場所にあった }

end;

destructor TDBCalendar.Destroy;

begin

FDataLink.Free; { 常に最初に所有オブジェクトを廃棄して ... }

inherited Destroy; { ... その後で継承デストラクタを呼び出す }

end;


Responding to data changes
Responding to data changes1101011

Section topics 	参照

現在，コントロールはデータリンクを持ち，データソースおよびデータ項目を指定するプロパティを備えています。次に必要なのは，項目データの変更に対応することです。変更が発生するのは，レコードの移動した場合か項目が変更された場合のいずれかです。

すべてのデータリンククラスには OnDataChange というイベントがあります。データソースからデータの変更を通知されると，データリンクオブジェクトは OnDataChange イベントに結び付けられているイベントハンドラを呼び出します。

データの変更に対応してコントロールを更新するには，データリンクの OnDataChange イベントにハンドラを結び付けます。

このサンプルでは，カレンダーにメソッドを追加して，それをデータリンクの OnDataChange イベントとして指定します。

次に示すように，DataChange メソッドを宣言して実行し，それをデータリンクの OnDataChange イベントに指定します。

例

type

TDBCalendar = class(TSampleCalendar)

private { 内部的な詳細はプライベートにする }

procedure DataChange(Sender: TObject); { イベントのパラメータを記述 }

end;

...

constructor TDBCalendar.Create(AOwner: TComponent);

begin

inherited Create(AOwner); { 常に最初に継承コンストラクタを呼び出す }

FReadOnly := True; { 元からある文 }

FDataLink := TFieldDataLink.Create; { データリンクオブジェクトを作成 }

FDataLink.OnDataChange := DataChange; { イベントにハンドラを結び付ける }

end;

destructor TDBCalendar.Destroy;

begin

FDataLink.OnDataChange := nil; { オブジェクトを廃棄する前にハンドラを除去 }

FDataLink.Free; { 常に最初に所有オブジェクトを廃棄して ... }

inherited Destroy; { ... その後で継承デストラクタを呼び出す }

end;

procedure TDBCalendar.DataChange(Sender: TObject);

begin

if FDataLink.Field = nil then { 項目が指定されていない場合には ... }

CalendarDate := 0 { ... 日付を無効にする }

else CalendarDate := FDataLink.Field.AsDateTime; { そうでなければカレンダーをその日付に設定 }

end;


Creating a data-editing control
Creating a data-editing control1101012

Section topics 	参照

データ編集コントロールを作成する場合は，コンポーネントを作成および登録してから，データ参照コントロールの場合と同様にデータリンクを追加します。基礎となる項目のデータ変更にも同様の方法で応答しますが，まだいくつかの問題を処理しなければなりません。

たとえば，コントロールにはキーイベントとマウスイベントの両方に応答させたいでしょう。コントロールは，ユーザーがコントロールの内容を変更した場合に応答しなければなりません。ユーザーがコントロールを終了した場合は，コントロールに加えられた変更をデータセットに反映しなければなりません。

ここで説明するデータ編集コントロールは，この章の最初の部分で説明したのと同じカレンダーコントロールです。このコントロールは，リンクした項目のデータの表示も編集もできるように変更されます。

既存のコントロールを変更してデータ編集コントロールにする手順は次のとおりです。

1.	FReadOnly のデフォルト値を変更します。

2.	マウスダウンメッセージとキーダウンメッセージを処理します。

3.	項目のデータリンククラスを更新します。

4.	Change メソッドを変更します。

5.	データセットを更新します。


Changing the default value of FReadOnly
Changing the default value of FReadOnly1101013

Section topics 	参照

これはデータ編集コントロールなので，ReadOnly プロパティはデフォルトで False に設定されます。ReadOnly プロパティを False にするには，コンストラクタで FReadOnly の値を変更します。

constructor TDBCalendar.Create(AOwner: TComponent);

begin

...

FReadOnly := False;	{ デフォルト値を設定する }

...

end;


Handling mouse-down and key-down messages
Handling mouse-down and key-down messages1101014

Section topics 	参照

コントロールのユーザーがコントロールと対話を始めると，コントロールは Windows からマウスダウンメッセージ（WM_LBUTTONDOWN，WM_MBUTTONDOWN，または WM_RBUTTONDOWN）またはキーダウンメッセージ（WM_KEYDOWN）を受け取ります。コントロールがこれらのメッセージに応答できるようにするには，これらのメッセージに応答するハンドラを記述しなければなりません。

Responding to mouse-down messages1101015

MouseDown メソッドは，コントロールの OnMouseDown イベント用のプロテクトメソッドです。コントロール自体が Windows のマウスダウンメッセージに応答して MouseDown メソッドを呼び出します。継承メソッド MouseDown をオーバーライドする場合は，OnMouseDown イベントの呼び出しに加えて，ほかの応答をするコードを含めることができます。

MouseDown をオーバーライドする手順は次のとおりです。

type

TDBCalendar = class(TSampleCalendar);

...

protected

procedure MouseDown(Button: TButton, Shift: TShiftState, X: Integer, Y: Integer);	override;

...

end;

procedure TDBCalendar.MouseDown(Button: TButton; Shift: TShiftState; X, Y: Integer);

var

MyMouseDown: TMouseEvent;

begin

if not ReadOnly and FDataLink.Edit then

inherited MouseDown(Button, Shift, X, Y)

else

begin

MyMouseDown := OnMouseDown;

if Assigned(MyMouseDown then MyMouseDown(Self, Button, Shift, X, Y);

end;

end;

MouseDown メソッドがマウスダウンメッセージに応答するときに，継承メソッド MouseDown が呼び出されるのは，コントロールの ReadOnly プロパティが False でデータリンクオブジェクトが編集モードの場合だけ，つまり項目を編集できる場合だけです。項目を編集できない場合，プログラマが OnMouseDown イベントハンドラに記述したコードがあれば実行されます。

Responding to key-down messages1101016

KeyDown メソッドは，コントロールの OnKeyDown イベント用のプロテクトメソッドです。コントロール自体が Windows のキーダウンメッセージに応答して KeyDown メソッドを呼び出します。継承メソッド KeyDown をオーバーライドする場合は，OnKeyDown イベントの呼び出しに加えて，ほかの応答をするコードも含めることができます。

KeyDown メソッドをオーバーライドする手順は次のとおりです。

1.	KeyDown メソッドを TDBCalendar クラスに追加します。

type

TDBCalendar = class(TSampleCalendar);

...

protected

procedure KeyDown(var Key: Word; Shift: TShiftState; X: Integer; Y: Integer);	override;

...

end;

2.	KeyDown メソッドを実装します。

procedure KeyDown(var Key: Word; Shift: TShiftState);

var

MyKeyDown: TKeyEvent;

begin

if not ReadOnly and (Key in [VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_END,

VK_HOME, VK_PRIOR, VK_NEXT]) and FDataLink.Edit then

inherited KeyDown(Key, Shift)

else

begin

MyKeyDown := OnKeyDown;

if Assigned(MyKeyDown) then MyKeyDown(Self, Key, Shift);

end;

end;

KeyDown メソッドがマウスダウンメッセージに応答するときに，継承メソッド KeyDown が呼び出されるのは，コントロールの ReadOnly プロパティが False であり，押されたキーがカーソルコントロールキーの 1 つであり，しかもデータリンクオブジェクトが編集モードの場合だけ，つまり項目を編集できる場合だけです。項目を編集できなかったりほかのキーが押された場合，プログラマが OnKeyDown イベントハンドラに記述したコードがあれば実行されます。


Updating the field data-link class
Updating the field data-link class1101017

Section topics 	参照

データ変更には以下の 2 種類があります。

データベース対応コントロールに反映しなければならない項目値の変更

項目値に反映しなければならないデータベース対応コントロールの変更

TDBCalendar コンポーネントは，データセット内の項目値が変更されたときにその変更値を CalendarDate プロパティに代入する DataChange メソッドをすでに持っています。DataChange メソッドは，OnDataChange イベント用のハンドラです。したがって，カレンダーコンポーネントは最初の種類のデータ変更を処理できます。

同様に項目のデータリンククラスは，コントロールのユーザーがデータベース対応コントロールの内容を変更したときに発生する OnUpdateData イベントも持っています。カレンダーコントロールは，OnUpdateData イベントのイベントハンドラになる UpdateData メソッドを持っています。UpdateData メソッドはデータベース対応コントロールの変更値を項目のデータリンクに代入します。

項目のデータリンククラスを更新するには，

1.	カレンダーの値に加えられた変更を項目値に反映するには，UpdateData メソッドをカレンダーコンポーネントの private セクションに追加します。

type

TDBCalendar = class(TSampleCalendar);

private

procedure UpdateData(Sender: TObject);

...

end;

2.	UpdateData メソッドを実装します。

procedure UpdateData(Sender: TObject);

begin

FDataLink.Field.AsDateTime := CalendarDate; {項目のリンクをカレンダー日付に設定する}

end;


Modifying the Change method
Modifying the Change method1101018

Section topics 	参照

TDBCalendar の Change メソッドは，新しい日付値が設定されるたびに呼び出されます。Change メソッドは，OnChange イベントハンドラがあれば呼び出します。コンポーネントユーザーは，日付の変更に応答するコードを OnChange イベントハンドラに記述できます。

カレンダー日付が変わると，変更が起きたことをデータセットに通知しなければなりません。この通知をするには，Change メソッドをオーバーライドし，コードをもう 1 行追加します。

実行する手順は次のとおりです。

1.	新しい Change メソッドを TDBCalendar コンポーネントに追加します。

type

TDBCalendar = class(TSampleCalendar);

private

procedure Change; override;

...

end;

2.	データセットにデータの変更を通知する Modified メソッドを呼び出し，次に継承メソッド Change を呼び出すよう Change メソッドを記述します。

TDBCalendar.Change;

begin

FDataLink.Modified; { Modified メソッドを呼び出す }

inherited Change; { 継承メソッド Change を呼び出す }

end;


Updating the dataset
Updating the dataset1101019

Section topics 	参照

これまでは，データベース対応コントロール内の変更で項目のデータリンククラス内の値が変わりました。データ編集コントロール作成の最終段階は，新しい値でデータセットを更新することです。データベース対応コントロールの値を変更した人がコントロールの外をクリックするか〔Tab〕キーを押してコントロールを終了した後に，この変更が行われなければなりません。

VCL にはコントロール操作用のメッセージコントロール ID が定義されています。たとえばユーザーがコントロールを終了すると，そのコントロールに CM_EXIT メッセージが送られます。そのメッセージに応答するメッセージハンドラを記述できます。この場合，ユーザーがコントロールを終了すると，CM_EXIT 用のメッセージハンドラである CMExit メソッドはそれに応答して，データセットのレコードを項目のデータリンククラスの変更値で更新します。メッセージハンドラについての詳細は，「メッセージの処理」を参照してください。

メッセージハンドラ内のデータセットを更新する手順は次のとおりです。

1.	メッセージハンドラを TDBCalendar コンポーネントに追加します。

type

TDBCalendar = class(TSampleCalendar);

private

procedure CMExit(var Message: TWMNoParams); message CM_EXIT;

...

end;

2.	CMExit メソッドを次のように実装します。

procedure TDBCalendar.CMExit(var Message: TWMNoParams);

begin

try

FDataLink.UpdateRecord; { データベースを更新するようにデータリンクに通知する}

except

on Exception do SetFocus; { 失敗した場合は，フォーカスが移動しないようにする}

end;

inherited;

end;


See also1101020

TDBCalendar

グリッドのカスタマイズ

データセットについて

メッセージの処理

ユーザーイベントについて


Making a dialog box a component
Making a dialog box a component1102001

Section topics 	参照

よく使うダイアログボックスは，コンポーネントにしてコンポーネントパレットに追加すると便利です。Delphi には標準 Windows コモンダイアログボックスを表すコンポーネントがありますが，同じような形式でダイアログボックスコンポーネントを作成できます。ダイアログボックスをコンポーネントにする目的は，プロジェクトに追加して設計時にプロパティを設定できるような，簡単なコンポーネントを作成することです。

ダイアログボックスをコンポーネントにする場合は，以下の作業が必要です。

1.	コンポーネントのインターフェースの定義

2.	コンポーネントの作成と登録

3.	コンポーネントのインターフェースの作成

4.	コンポーネントのテスト

ダイアログボックスに関連付けられた Delphi の「ラッパー」コンポーネントは，実行時にダイアログボックスを作成し，ユーザーが指定したデータを渡します。ダイアログボックスコンポーネントは再利用でき，カスタマイズも可能です。

オブジェクトリポジトリに登録されている［バージョン表示］ダイアログを表示するラッパーコンポーネントと同じものを作成します。

メモ	ABOUT.PAS ファイルと ABOUT.DFM ファイルを作業用ディレクトリにコピーします。

コンポーネント化するダイアログボックスを設計する場合，制限はそれほどありません。また，ほとんどのフォームはダイアログボックスとして動作できます。


Defining the component interface
Defining the component interface1102002

Section topics 	参照

ダイアログボックス用のコンポーネントを作成する場合，まずアプリケーション開発者から見てどのようなコンポーネントを作成するのかという点を考察します。つまり，ダイアログボックスとそれを使用するアプリケーションとの間のインターフェースを考案します。

たとえば，コモンダイアログボックスコンポーネントにはプロパティがあります。アプリケーション開発者はそのプロパティをとおしてキャプションやコントロールを初期設定し，またダイアログボックスが閉じられた後は必要な情報を読み出します。この場合，情報を直接やり取りするのはラッパーコンポーネントのプロパティであって，ダイアログボックスのコントロールではありません。

インターフェースは情報を十分に受け渡す必要があります。つまり，アプリケーションが希望する形でダイアログボックスフォームを表示し，また，アプリケーションが必要とする情報を返す必要があります。コンポーネントのプロパティは，ダイアログボックスに表示されるすべてのデータを扱うものと考えてください。


Creating and registering the component
Creating and registering the component1102003

Section topics 	参照

コンポーネントの作成は常に同じ方法で開始します。ユニットを作成し，コンポーネントクラスを派生させて登録し，コンパイルしてコンポーネントパレットにインストールします。

このサンプルでは，一般的な手順でコンポーネントを作成します。コンポーネントに固有の点は以下のとおりです。

コンポーネントユニットの名前は AboutDlg とする

TComponent から TAboutBoxDlg という新しいコンポーネント型を派生させる

TAboutBoxDlg をコンポーネントパレットの［Samples］ページに登録する

作成したユニットのコードは次のようになります。

unit AboutDlg;

interface

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms;

type

TAboutBoxDlg = class(TComponent)

end;

procedure Register;

implementation

procedure Register;

begin

RegisterComponents('Samples', [TAboutBoxDlg]);

end;

end.

この新しいコンポーネントの機能は TComponent に組み込まれている機能だけです。つまり，これは最も単純な非ビジュアルコンポーネントです。次の節では，このコンポーネントとダイアログボックスとの間のインターフェースを作成します。


Creating the component interface
Creating the component interface1102004

Section topics 	参照

コンポーネントのインターフェースを作成する手順は以下のとおりです。

1.	フォームユニットファイル files

2.	インターフェースプロパティの追加

3.	Execute メソッドの追加


Including the form unit
Including the form unit1102005

Section topics 	参照

ラッパーコンポーネントがダイアログボックスを初期化して表示するには，そのフォームユニットをラッパーコンポーネントのユニットの uses 節に記述します。

AboutDlg ユニットの uses 節に About ユニットを追加します。

新しい uses 節は次のようになります。

uses

SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms

About;

フォームユニットでは，必ずそのフォームクラスのインスタンスが宣言されています。［バージョン表示］ダイアログボックスのフォームクラスは TAboutBox なので，About ユニットには次の宣言があります。

var

AboutBox: TAboutBox;

そのため，uses 節に About を追加すればラッパーコンポーネントは AboutBox を操作できます。


Adding interface properties
Adding interface properties1102006

Section topics 	参照

アプリケーション開発者がダイアログボックスをコンポーネントとして使用するにはいくつかのプロパティが必要です。そこで，必要なプロパティの宣言をコンポーネントのクラス宣言に記述します。

ラッパーコンポーネントのプロパティは，通常のコンポーネントのプロパティよりも単純です。ここで作成するのは，ラッパーコンポーネントがダイアログボックスとの間で受け渡すための永続的なデータです。このデータをプロパティのフォームで保持しておくと，アプリケーション開発者が設計時にデータを指定し，ラッパーコンポーネントが実行時にそのデータをダイアログボックスに渡せます。

インターフェースプロパティの宣言は，コンポーネントのクラス宣言の published 部に記述します。このプロパティの宣言には以下に示す 2 つの部分があります。

クラスフィールドの宣言。ラッパーコンポーネントがプロパティの値を格納するための変数を宣言する

プロパティ自体の宣言。プロパティの名前を宣言し，値の格納場所として使用するフィールドを指定する

インターフェースプロパティには，アクセスメソッドは不要です。このプロパティは格納されているデータに直接アクセスします。プロパティ値を格納するクラスフィールドの名前は通常，プロパティ名の先頭に F を加えた名前にします。フィールドとプロパティは必ず同じ型にします。

例

たとえば，Year という整数型のインターフェースプロパティを宣言するコードを次に示します。

type

TMyWrapper = class(TComponent)

private

FYear: Integer; {Year プロパティのデータを格納するフィールド}

published

property Year: Integer read FYear write FYear; {フィールドと対応するプロパティ}

end;

［バージョン表示］ダイアログボックスの場合には 4 つの string 型のプロパティが必要です。各プロパティはそれぞれ，製品名，バージョン情報，著作権情報，コメントを表します。

type

TAboutBoxDlg = class(TComponent)

private

FProductName, FVersion, FCopyright, FComments: string; {フィールドを宣言}

published

property ProductName: string read FProductName write FProductName;

property Version: string read FVersion write FVersion;

property Copyright: string read FCopyright write FCopyright;

property Comments: string read FComments write FComments;

end;

ここで，このコンポーネントをコンポーネントパレットにインストールしてフォームに配置すればプロパティの設定ができます。プロパティの値はフォームに保持され，ラッパーコンポーネントはダイアログボックスを実行するときにこの値を使用できます。


Adding the Execute method
Adding the Execute method1102007

Section topics 	参照

最後に，コンポーネントのインターフェースには，ダイアログボックスを開く方法とダイアログボックスを閉じて戻り値を取得する方法を用意します。コモンダイアログボックスコンポーネントには Execute という論理型関数があり，ダイアログボックスで OK が選択されたときは True を返し，キャンセルされたときは False を返します。

Execute メソッドの宣言の例を次に示します。

type

TMyWrapper = class(TComponent)

public

function Execute: Boolean;

end;

Execute には少なくとも次の機能が必要です。つまり，ダイアログボックスフォームを作成し，モード付きダイアログボックスとして表示し，ShowModal からの戻り値に応じて True か False を返します。

例

TMyDialogBox 型のダイアログボックスフォームの Execute メソッドの例を次に示します。この Execute メソッドには最小限の機能しかありません。

function TMyWrapper.Execute: Boolean;

begin

DialogBox := TMyDialogBox.Create(Application); {フォームを作成}

try

Result := (DialogBox.ShowModal = IDOK); 	{実行し，閉じられた方法によって結果を設定}

finally

DialogBox.Free; {フォームを破棄}

end;

end;

このコードでは，例外が発生した場合でも確実にダイアログボックスオブジェクトを破棄できるように try..finally ブロックを使用しています。一般にこのような方法でオブジェクトを作成した場合は，常に try..finally ブロックを使用してコードを保護し，アプリケーションが割り当てたすべてのリソースを確実に解放するようにします。

実際には try..finally ブロック中にはより多くのコードを記述します。たとえば，ShowModal を呼び出す前に，ラッパーコンポーネントのインターフェースプロパティに基づいてダイアログボックスのプロパティを設定します。また，ShowModal を呼び出した後，ダイアログボックスの実行結果に基づいてインターフェースプロパティを設定することもあります。

この［バージョン表示］ダイアログボックスの場合には，ラッパーコンポーネントの 4 つのインターフェースプロパティを使用して，［バージョン表示］ダイアログボックスフォームのラベルの内容を設定します。［バージョン表示］ダイアログボックスはアプリケーションに情報を返さないので，ShowModal を呼び出した後は何もする必要はありません。［バージョン表示］ダイアログボックスのラッパーコンポーネントの Execute メソッドは次のように記述します。

TAboutDlg クラスの public 部内では，Execute メソッドの宣言を追加します。

type

TAboutDlg = class(TComponent)

public

function Execute: Boolean;

end;

function TAboutBoxDlg.Execute: Boolean;

begin

AboutBox := TAboutBox.Create(Application); {［バージョン表示］ダイアログボックスを作成}

try

if ProductName = '' then {製品名が空白の場合は ...}

ProductName := Application.Title; {...かわりにアプリケーションのタイトルを使用}

AboutBox.ProductName.Caption := ProductName; {製品名をコピー}

AboutBox.Version.Caption := Version; {バージョン情報をコピー}

AboutBox.Copyright.Caption := Copyright; {著作権情報をコピー}

AboutBox.Comments.Caption := Comments; {コメントをコピー}

AboutBox.Caption := 'About ' + ProductName; {［バージョン表示］ダイアログボックスのキャプションを設定}

with AboutBox do

begin

ProgramIcon.Picture.Graphic := Application.Icon; { アイコンをコピー}

Result := (ShowModal = IDOK); {実行して結果を設定}

end;

finally

AboutBox.Free; {［バージョン表示］ダイアログボックスを破棄}

end;

end;


Testing the component
Testing the component1102008

Section topics 	参照

いったんダイアログボックスコンポーネントをインストールした後は，フォームにそれを配置して実行できます。テスト方法はコモンダイアログボックスの場合と同じです。［バージョン表示］ダイアログボックスを簡単にテストするには，フォームにコマンドボタンを追加し，そのボタンが選択されときにダイアログボックスを実行するようにします。

たとえば，［バージョン表示］ダイアログボックスを作成してコンポーネントにし，コンポーネントパレットに追加したとします。このコンポーネントは次の手順で実行できます。

1.	新しいプロジェクトを作成します。

2.	［バージョン表示］ダイアログボックスコンポーネントをメインフォームに配置します。

3.	フォームにコマンドボタンを配置します。

4.	コマンドボタンをダブルクリックして，空のクリックイベントハンドラを作成します。

5.	クリックイベントハンドラに次のコード行を記述します。

AboutBoxDlg1.Execute;

6.	アプリケーションを実行します。

メインフォームが表示されたら，コマンドボタンをクリックします。［バージョン表示］ダイアログボックスが現れ，デフォルトのプロジェクトアイコンと Project1 という名前が表示されます。ダイアログボックスを閉じるには，OK を選択します。

［バージョン表示］ダイアログボックスコンポーネントでは，プロパティを設定できます。プロパティを設定してアプリケーションを再度実行すれば，プロパティの設定を反映したダイアログボックスが表示されます。


See also1102009

コンポーネントに共通の作業

コンポーネントパレット

コンポーネントパレットのカスタマイズ


Building a dialog box into a DLL
Building a dialog box into a DLL1103001

Section topics	参照

Delphi アプリケーションでも，ほかのツールで作成したプログラムでも，同じダイアログボックスを使いたいことがあります。その場合は，どの Windows プログラムからでも呼び出せる標準のダイナミックリンクライブラリ（DLL）としてコンポーネントを構築できます。

メモ	TForm から派生したコンポーネントだけをスタンドアロンの DLL にできます。特定の Delphi コンポーネントに関連付けられていないルーチンをカプセル化する DLL も作成できます。ボタンなどの個々のコンポーネントを Delphi 以外のアプリケーションで使えるように（フォームの外で）コンパイルすることはできません。

requires 節を使って間接的に外部コンポーネントを利用する Delphi パッケージと異なり，各 DLL にはコンポーネントライブラリ全体のオーバーヘッド（約 100KB）を含めなければなりません。いくつかのダイアログボックスを単一の DLL にまとめれば，このオーバーヘッドを軽減できます。

たとえば，パスワードのチェック，共有データの表示，ステータス情報の更新などを行ういくつかのダイアログボックスがあり，複数のアプリケーションがそれを共有しているとします。この場合，複数のダイアログボックスを単一の DLL に組み込めば，各ダイアログボックスはコンポーネントライブラリのオーバーヘッドを共有できます。

メモ	DLL を操作する前に，Windows で .DLL ファイルの表示が可能なことを確認してください。Windows エクスプローラを開き，［表示(V)｜オプション(O)］を選択し，［表示］タブをクリックします。.DLL ファイルの種類が隠しファイルとしてマークされている場合，.DLL ファイルはファイル選択ダイアログには表示されません。

ダイアログボックスを DLL 化する 3 つの手順は以下のとおりです。

インターフェースルーチンの追加

プロジェクトファイルの変更

アプリケーションからダイアログボックスを開く


Adding the interface routine
Adding the interface routine1103002

Section topics	参照

ダイアログボックスを DLL 化する場合，そのダイアログボックス用のインターフェースルーチンが必要です。これはダイアログボックス用のラッパーコンポーネントを作成することに似ています。しかし DLL の場合は，ダイアログボックスを呼び出すアプリケーションが Delphi で開発されたものではない可能性があるため，メソッドとプロパティを持つコンポーネントを作成するかわりに，独立した手続きまたは関数をインターフェースとしてエクスポートします。

最も簡単で実用的なのは，1 つの関数を定義してインターフェースルーチンとすることです。その関数では，アプリケーション開発者がダイアログボックスに設定する可能性があるすべてのプロパティをパラメータとして受け取り，ダイアログボックスの実行結果を示す値を返します。ダイアログボックスがアプリケーションに情報を返さない場合は，関数のかわりに手続きを使用します。

インターフェースルーチンの宣言はダイアログボックスのフォームユニットのインターフェース部に記述し，ルーチンの実装は実現部に記述します。


Declaring the interface routine
Declaring the interface routine1103003

Section topics	参照

インターフェースルーチンになる関数および手続きは，フォームユニットのインターフェース部で宣言します。そのとき，末尾に export 指令を記述して，外部のコードがそのルーチンにアクセスできるようにします。

Object Pascal 以外の言語から呼び出すインターフェースルーチンの場合は，必ずパラメータと戻り値はその呼び出し側の言語で使用できる型として宣言してください。たとえば，文字列を渡す場合には， Object Pascal 固有の型である string 型ではなく，ヌルで終わる文字配列（Object Pascal の PChar 型）を使用します。

例

TPasswordForm 型のダイアログボックスフォームが入っているフォームユニットで，インターフェース部に次の宣言を追加します。

unit PassForm;

interface

uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Forms, Controls,

Forms, Dialogs, StdCtrls, Buttons;

type

TPasswordForm = class(TForm)

...	{ ここにさまざまな宣言が記述される }

end;

var

PasswordForm: TPasswordForm;

function GetPassword(APassword: PChar): WordBool; export;

インターフェースルーチンの宣言の最後は export 指令でなければなりません。この指令により，DLL はインターフェースルーチンを外部のプログラムにエクスポートします。


Implementing the interface routine
Implementing the interface routine1103004

Section topics	参照

インターフェースルーチンを宣言した後は，そのルーチンを実現するだけです。次のコードは，インターフェースルーチンの基本的な構造を示しています。

function DoDialog(...): ReturnType; { 手続きの場合もある }

begin

Result := DefaultValue; { デフォルトの戻り値を設定 }

DialogBox := TDialogBoxType.Create(Application); { インスタンスを作成 }

try

if DialogBox.ShowModal = IDOK then { 実行して結果を判定 }

{ ユーザーがダイアログボックスで［OK］を選択したときの Result を設定 }

else

{ ユーザーがダイアログボックスをキャンセルしたときの Result を設定 };

finally

DialogBox.Free; { ダイアログボックスインスタンスを破棄 }

end;

end;

例

次の例では，パスワード入力ダイアログボックスを実行し，ユーザーが入力したパスワードをパラメータとして渡されたパスワードと比較し，一致した場合に trueを返しています。

function GetPassword(APassword: PChar): WordBool;

begin

Result := False;	{ 開始時には，入力が正しくないと仮定する }

PasswordForm := TPasswordForm.Create(Application);

try

if PasswordForm.ShowModal = IDOK then	{ ［OK］が選択された場合はパスワードを判定 }

if CompareText(PasswordForm.PasswordField.Text, StrPas(APassword)) = 0 then

Result := true

else MessageDlg('Invalid password', mtWarning, [mbOK], 0);

finally

PasswordForm.Free;

end;

end;

文字列を比較する前に，ヌルで終わる文字列を Object Pascal の文字列に変換するために StrPas 関数を呼び出す必要があります。


Modifying the project file
Modifying the project file1103005

Section topics	参照

ダイアログボックス用のインターフェースルーチンを作成したので，次はプロジェクトファイルを変更して，アプリケーションではなく DLL を作成するようにします。プロジェクトファイルの変更方法を次に示します。

ファイルの先頭行の予約語 program を library に変更します。

プロジェクトの uses 節から Forms ユニットを削除します。

ファイルの最後にある begin と end の間のコードをすべて削除します。

uses 節より後で begin..end ブロックより前の位置に予約語 exports を追加し，それに続けてダイアログボックスのインターフェースルーチンの名前を記述し，最後にセミコロンを付けます。

これで，プロジェクトをコンパイルすると，アプリケーションのかわりに DLL が作成されます。アプリケーションは，この DLL を呼び出して組み込まれているダイアログボックスを開くことができます。

例

代表的な変更前のプロジェクトファイルの例を次に示します。

program Password;

uses

Forms,

PassForm in 'PASSFORM.PAS' {PasswordForm};

{$R *.RES}

begin

Application.CreateForm(TPasswordForm, PasswordForm);

Application.Run;

end.

上のファイルを，DLL を作成するように変更した例を次に示します。インターフェースルーチンとして GetPassword という関数を指定しています。

library Password; { 予約語を変更 }

uses	{ Forms を削除した }

PassForm in 'PASSFORM.PAS' {PasswordForm};

exports

GetPassword; { exports 節を追加した }

{$R *.RES}

begin	{ メインブロックのコードを削除した }

end.


Opening the dialog box from an application
Opening the dialog box from an application1103006

Section topics	参照

ダイアログボックスを DLL 化して DLL をコンパイルしたら，このダイアログボックスをアプリケーションから使用できます。

DLL からダイアログボックスを使用する場合は，以下の作業が必要です。

1.	DLL からインターフェースルーチンをインポートする

2.	インターフェースルーチンを呼び出す

アプリケーションから DLL を呼び出す方法は，そのアプリケーションが開発されたツールにかかわりなく常に同じです。以下では，作成した DLL 関数を例に取り，さまざまな環境からその関数を呼び出す方法について簡単に説明します。


Opening the dialog box from a Delphi application
Opening the dialog box from a Delphi application1103007

Section topics	参照

インターフェースルーチンをインポートする方法は簡単です。ルーチンを呼び出すユニットの実現部でそのルーチンを宣言し，続けて予約語 external と DLL の名前を記述します。

たとえば，PASSWORD.DLL という DLL から GetPassword というインターフェースルーチンをインポートするには，インポートするユニットに次のコードを追加します。

function GetPassword(APassword: PChar): WordBool; far;

external 'PASSWORD';

これで，このユニットのコードは，インポートするルーチンを普通のルーチンと同じように呼び出せます。

GetPassword のインポートを実行するには，たとえばメインフォームに 1 つのコマンドボタンを配置して簡単なプロジェクトを作成します。パスワード入力ダイアログボックス用のインターフェースルーチンをインポートした後，次のようにしてこのパスワード入力ダイアログボックスを使用するクリックイベントハンドラを追加します。

procedure TForm1.Button1Click(Sender: TObject);

begin

if GetPassword('PASSWORD') then

Color := clGreen

else

Color := clRed;

end;

ユーザーが正しいパスワードを入力した場合には，アプリケーションはフォームを緑色に変えます。ユーザーが不正なパスワードを入力したか，ダイアログボックスをキャンセルした場合には，フォームは赤色に変わります。


Opening the dialog box from a Paradox application
Opening the dialog box from a Paradox application1103008

Section topics	参照

Paradox for Windows のアプリケーションにインターフェースルーチンをインポートする方法は，Delphi アプリケーションの場合と似ています。Paradox にはユニットがないので，このルーチンを呼び出すオブジェクトで Uses ブロックを記述します。

たとえば，あるボタンが PASSWORD.DLL の GetPassword 関数を呼び出す場合には，そのボタンの Uses ウィンドウで次のコードを記述します。

Uses Password

GetPassword(APassword CPTR) CWORD

endUses

これで，Delphi アプリケーションの場合と同じような方法でインポートを実行できます。ボタンオブジェクトを持つフォームを新しく作成し，PASSWORD.DLL から GetPassword をインポートします。その後，次のようにボタンの pushButton メソッドを変更して GetPassword を呼び出します。

method pushButton(var eventInfo Event)

if GetPassword("PASSWORD") <> 0 then

#Page2.Color = Green

else

#Page2.Color = Red

endIf

endmethod


Opening the dialog box from a dBASE application
Opening the dialog box from a dBASE application1103009

Section topics	参照

dBASE for Windows のアプリケーションにインターフェースルーチンをインポートする方法は，Delphi アプリケーションの場合と似ています。

次の小さなプログラムは，PASSWORD.DLL から GetPassword 関数をインポートします。

LOAD DLL PASSWORD.DLL

EXTERN CLOGICAL GetPassword(CSTRING) PASSWORD.DLL

DO PWTEST.WFM

このプログラムが呼び出している PWTEST.WFM ファイルでは，ボタンを含むフォームを定義します。そのボタンには次のコードを記述します。

Procedure PUSHBUTTON1_OnClick

IF GetPassword("PASSWORD")

Form.ColorNormal = "G/G"

ELSE

Form.ColorNormal = "R/R"

ENDIF


Opening the dialog box from a C/C++ application
Opening the dialog box from a C/C++ application1103010

Section topics	参照

C や C++ で作成したアプリケーションにインターフェースルーチンをインポートするには次の手順に従います。

1.	プログラムのメインソースコードで関数名を宣言します。たとえば，次のように宣言します。

extern BOOL GetPassword(LPSTR);

2.	PASSWORD.DLL に対して IMPLIB ユーティリティを実行し，作成された .LIB ファイルをプロジェクトに追加します。その後プロジェクトをコンパイルすれば，関数は自動的にインポートされます。

これで，アプリケーションからインポートした関数を呼び出せます。たとえば，ObjectWindows ライブラリを使用して，ボタンを含むフォームで構成される C++ アプリケーションを作成します。さらに，ユーザーがボタンを押すと GetPassword が呼び出されるように次のメソッドを記述します。

void TTestWindow::ButtonPressed()

{

if (GetPassword("PASSWORD"))

SetBkgndColor(TColor::LtGreen);

else

SetBkgndColor(TColor::LtRed);

Invalidate();

}


See also1103011

TForm


Creating Internet server applications
Creating Internet server applications1120001

Section topics 	参照

Delphi では，非ビジュアルコンポーネントを入れることができる CGI アプリケーションまたはダイナミックリンクライブラリ（DLL）として Web サーバーアプリケーションを作成できます。インターネット固有のコンポーネントを使うと，特定の Uniform Resource Identifier（URI）に関連付けられたイベントハンドラを簡単に作成できるほか，処理が完了したときにプログラム上で HTML ドキュメントを作成し，クライアントに転送することもできます。

このコンテンツはデータベースから取り出されることがよくあります。Delphi インターネットコンポーネントを使うとデータベースへの接続を自動的に管理できるので，1 つの DLL で複数のスレッド保障データベース接続を同時に処理できます。

この章では，これらのインターネットコンポーネントについて説明するほか，何種類かのインターネットアプリケーションを作成する方法も取り上げます。また，ActiveForms をインターネットサーバーアプリケーションとして使用することもできます。ActiveForms については，「ActiveX Form」を参照してください。


Terminology and standards
Terminology and standards1120002

Section topics 	参照

インターネット上の動作を制御するプロトコルの多くは，Request for Comment（RFC）ドキュメントで定義されています。このドキュメントは，インターネットプロトコルのエンジニアリングと開発の部門である Internet Engineering Task Force（IETF）が作成，更新，管理を行っています。インターネットアプリケーションを作成するときに役立つ主な RFC には以下のものがあります。

RFC822 『Standard for the format of ARPA Internet text messages』。メッセージヘッダーの構造，およびそのと内容について説明しています。

RFC1521 『MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies』。マルチパートやマルチフォーマットのメッセージをカプセル化して転送するための方法について説明しています。

RFC1945 『Hypertext Transfer Protocol � HTTP/1.0』。ハイパードキュメントを配布するために使う転送プロトコルについて説明しています。

IETF の Web サイト www.ietf.cnri.reston.va.us には RFC のライブラリがあります。


Parts of a Uniform Resource Locator
Parts of a Uniform Resource Locator1120003

Section topics 	参照

Uniform Resource Locator（URL）は，ネット上で利用できるリソースの位置を完全な形式で記述したものです。複数の要素から構成されており，そのそれぞれにアプリケーションがアクセスできます。

URL の構成要素

URI vs. URL1120004

URL は HTTP 標準 RFC1945 で定義されている Uniform Resource Identifier（URI）の部分集合です。Web サーバーアプリケーションは，最終結果が特定の位置になく必要に応じて作成されるいくつものソースからコンテンツを生成することがよくあります。URI は，特定の位置にないリソースを記述できます。


An overview of HTTP server activity
An overview of HTTP server activity1120005

Section topics 	参照

Web ブラウザのクライアント／サーバーの特徴は見た目は単純です。ほとんどのユーザーにとっては，World Wide Web での情報検索は，リンクをクリックして情報を画面に表示するだけの簡単な操作です。より詳細な知識があるユーザーならば HTML 構文のほか，実際に使うプロトコルのクライアント／サーバーの特徴をある程度理解しています。ページ単位の単純な Web サイトコンテンツを作成する場合，通常はそれで十分です。もっと複雑な Web ページを作成する場合は，HTML を使って情報を自動的に収集して表示するために，さまざまな方法を利用できます。

HTML ドキュメントの収集と表示に役立つ Delphi コンポーネントについて説明する前に，クライアントがリクエストを送りサーバーがリクエストを処理する方法について詳細に説明します。ここでは，以下の内容について説明します。

クライアントがリクエストを作成する方法

Web サーバーがリクエストを受信したときの処理

ページ作成プログラムが Web サーバーから情報を受信する方法

結果を Web サーバーに返す方法


Composing client requests
Composing client requests1120006

Section topics 	参照

HTML ハイパーテキストリンクを選択するかユーザーが URL を指定すると，ブラウザはプロトコル，指定されたドメイン，情報へのパス，日時，動作環境，ブラウザ自身などのコンテンツ情報を収集します。次にリクエストを作成します。

たとえば，フォームのボタンをクリックして選択した基準に基づいてイメージページを表示するには，クライアントは次の URL を作成します。

http://www.TSite.com/art/gallery.dll/animals?animal=dog&color=black

これは，www.TSite.com ドメインの HTTP サーバーを指定します。クライアントは www.TSite.com に連絡をとり，HTTP サーバーに接続し，リクエストをそのサーバーに渡します。次にリクエストの例を示します。

GET /art/gallery.dll/animals?animal=dog&color=black HTTP/1.0

Connection: Keep-Alive

User-Agent: Mozilla/3.0b4Gold (WinNT; I)

Host: www.TSite.com:1024

Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*


Serving client requests
Serving client requests1120007

Section topics 	参照

サーバーはこのリクエストを受信すると，サーバーの環境設定に基づいて動作をいくつでも実行できます。リクエストの /gallery.dll 部分をプログラムとして認識するようにサーバーが設定されている場合，リクエストの情報がプログラムに渡される方法はプログラムの種類によって異なります。

プログラムが Common Gateway Interface（CGI）の場合，サーバーはリクエストの情報を CGI プログラムに直接渡す。サーバーはプログラムが終了するまで待機している。CGI プログラムは終了すると，コンテンツをサーバーに直接返す

プログラムが Win-CGI の場合，サーバーはファイルを開き，リクエストの情報を書き込んで，Win-CGI プログラムを実行する。また，クライアント情報が入っているファイルの位置や Win-CGI プログラムがコンテンツを作成するために使うファイルの位置を渡す。サーバーはプログラムが終了するまで待機している。Win-CGI プログラムが終了すると，このプログラムが書き込んだコンテンツファイルからサーバーがデータを読み出す

プログラムがダイナミックリンクライブラリ（DLL）の場合，サーバーは必要であれば DLL をロードしてからリクエストの情報を構造体として DLL に渡す。サーバーはプログラムが終了するまで待機している。DLL は終了すると，コンテンツをサーバーに直接返す

どの場合も，プログラムはリクエストに基づいて動作し，プログラマが指定した動作（データベースへのアクセス，単純なテーブル参照や計算，HTML ドキュメントの作成または選択など）を実行します。


Responding to client requests
Responding to client requests1120008

Section topics 	参照

プログラムはクライアントリクエストの処理が完了すると，HTML コードやその他の MIME コンテンツのページを作成し，サーバーを経由してそのページを表示用にクライアントに返します。レスポンスを返す方法もプログラムの種類によって異なります。

Win-CGI スクリプトは終了すると，HTML ページを作成し，それをファイルに書き込み，レスポンス情報を別のファイルに書き込み，この 2 つのファイルの位置をサーバーに返す。サーバーは両方のファイルを開き，HTML ページをクライアントに返す

DLL は終了すると，HTML ページとすべてのレスポンス情報をサーバーに直接返す。サーバーはこれをクライアントに返す

Web サーバーアプリケーションを DLL として作成すると，個々のリクエストに対処するために必要な処理の数やディスクへのアクセス回数が減るので，システムの負荷やリソースの使用量を軽減できます。


Web server applications
Web server applications1120009

Section topics 	参照

Web サーバーアプリケーションは既存の Web サーバーの機能を拡張します。Web サーバーアプリケーションは Web サーバーから HTTP リクエストメッセージを受信し，メッセージで要求された動作を実行し，レスポンスを作成して Web サーバーに返します。Delphi アプリケーションで実行できる操作はどれも Web サーバーアプリケーションに組み込むことができます。

Types of Web server applications1120010

Delphi を使うと 4 つの Web サーバーアプリケーションを作成できます。アプリケーションごとに，TWebApplication，TWebRequest，TWebResponse のどの下位オブジェクトを使うかが決まっています。

アプリケーションの種類	アプリケーションオブジェクト	リクエストオブジェクト	レスポンスオブジェクト
Microsoft サーバー DLL（ISAPI）	TISAPIApplication	TISAPIRequest	TISAPIResponse
Netscape サーバー DLL（NSAPI）	TISAPIApplication	TISAPIRequest	TISAPIResponse
コンソール CGI アプリケーション	TCGIApplication	TCGIRequest	TCGIResponse
Windows CGI アプリケーション	TCGIApplication	TWinCGIRequest	TWinCGIResponse
ISAPI and NSAPI1120011

ISAPI または NSAPI の Web サーバーアプリケーションは Web サーバーがロードする DLL です。クライアントリクエスト情報は構造体として DLL に渡されます。TISAPIApplication はこの情報を評価して，ディスパッチャ，TISAPIRequest オブジェクト，TISAPIResponse オブジェクトを作成します。

CGI standalone1120012

CGI スタンドアロンの Web サーバーアプリケーションは，標準入力でクライアントリクエストを受信し，標準出力で結果をサーバーに返すコンソールアプリケーションです。TCGIApplication はこのデータを評価して，ディスパッチャ，TCGIRequest オブジェクト，TCGIResponse オブジェクトを作成します。

WinCGI standalone1120013

Win-CGI スタンドアロンの Web サーバーアプリケーションは，サーバーが書き込んだ環境設定（INI）ファイルからクライアントリクエスト情報を受信し，結果をサーバーがクライアントに返すファイルに書き込む Windows アプリケーションです。TCGIApplication は INI ファイルを評価して，ディスパッチャ，TWinCGIRequest オブジェクト，TWinCGIResponse オブジェクトを作成します。


Creating Web server applications
Creating Web server applications1120014

Section topics 	参照

Delphi の新しい Web サーバーアプリケーションは，Delphi メインウィンドウメニューで［File｜New］を選択してから，［New Items］ダイアログボックスで［Web Server Application］を選択して作成します。このダイアログボックスで選択できる Web サーバーアプリケーションは，以下の 3 つに分類されます。

ISAPI とNSAPI	これを選択すると，プロジェクトファイルのライブラリヘッダーと要求されたエントリがプロジェクトファイルの uses リストと exports 節に追加される
CGI スタンドアロン	これを選択すると，要求されたエントリがプロジェクトファイルの uses 節に追加され，適切な $APPTYPE 指令がソースに追加される
Win-CGI スタンドアロン	これを選択すると，要求されたエントリがプロジェクトファイルの uses 節に追加され，適切な $APPTYPE 指令がソースに追加される

Web サーバーアプリケーションを選択するときは，開発者のアプリケーションが使う Web サーバーの種類と通信できる種類を選択します。これにより，インターネットコンポーネントを使い，空の Web モジュールを持つように設定された新しいプロジェクトが作成されます。

Web モジュールは TDataModule の下位オブジェクトであり，TDataModule と同じように Web アプリケーションでビジネスルールと非ビジュアルコンポーネントを集中管理するために使えます。

警告	DLL ベースの Web サーバーアプリケーションの Web モジュールは，レスポンス時間を速くするために後で再使用できるようにキャッシングされています。ディスパッチャの状態と動作リストは，リクエストごとには再初期化されません。実行時に動作項目の Enabled プロパティまたは Default プロパティを変更すると，それ以降のクライアントリクエストでこのモジュールを使ったときに予想外の結果が生じることがあります。


Setting up the Web module
Setting up the Web module1120015

Section topics 	参照

Web モジュールは，アプリケーションで使う非ビジュアルコンポーネントやビジネスルールのリポジトリとして機能します。アプリケーションがレスポンスメッセージを作成するときに使うコンテンツプロデューサを追加してください。このようなコンテンツプロデューサは，Delphi に用意されているコンテンツプロデューサ（TPageProducer，TDataSetTableProducer，TQueryTableProducer など）でも，開発者が自分で作成した TCustomContentProducer の下位オブジェクトでもかまいません。レスポンスのコンテンツを記述したヘルパーオブジェクト（THTMLTableAttributes や THTMLTableCellAttributes など）も追加します。データベースのデータが入っているレスポンスメッセージをアプリケーションで生成する場合，データアクセスコンポーネント（TSession，TDatabase，TTable，TQuery，TStoredProc，TBatchMove など）を追加します。

Web モジュールは非ビジュアルコンポーネントやビジネスルールを格納するだけでなく，ディスパッチャとして機能します。つまり，受信した HTTP リクエストメッセージを，そのリクエストへのレスポンスを生成する動作項目に対応付けます。

開発者は Web アプリケーションで使う非ビジュアルコンポーネントやビジネスルールがいくつも入っているデータモジュールをすでに用意しているかもしれません。その場合は，Web モジュールを自分の既存のデータモジュールで置き換えられます。これには，自動生成された Web モジュールを削除し，かわりに自分のデータモジュールを追加します。次にそのデータモジュールに TWebDispatcher コンポーネントを追加して，データモジュールが Web モジュールと同様に動作項目にリクエストメッセージをディスパッチできるようにします。受信した HTTP リクエストメッセージに応答する動作項目の選択方法を変更するには，TCustomWebDispatcher から新しいディスパッチャコンポーネントを派生させて，データモジュールに追加します。

プロジェクトに入れられるディスパッチャは 1 つだけです。このディスパッチャにできるのは，プロジェクトを作成すると自動的に生成される Web モジュールか，Web モジュールのかわりとしてデータモジュールに追加する TWebDispatcher コンポーネントです。ディスパッチャが入っているデータモジュールを実行時にもう 1 つ作成すると，Web サーバーアプリケーションは実行時エラーを生成します。

メモ	設計時に設定する Web モジュールは実際にはテンプレートです。ISAPI アプリケーションと NSAPI アプリケーションでは，リクエストメッセージごとに別々のスレッドが生成され，スレッドごとに Web モジュールの別々のインスタンスとリクエストのコンテンツが動的に作成されます。


The Web Application object
The Web Application object1120016

Section topics 	参照

Web アプリケーション用に設定するプロジェクトには，Application というグローバル変数が入っています。Application は TWebApplication の下位オブジェクトで，作成するアプリケーションの種類に合わせて TISAPIApplication または TCGIApplication に決まります。Web サーバーが HTTP リクエストメッセージを受信するとそれに応答して実行されます。

警告	プロジェクトファイルの uses リストの CGIApp ユニットまたは ISAPIApp ユニットの後に Forms ユニットを入れないでください。Forms ユニットもグローバル変数 Application を宣言します。CGIApp ユニットまたは ISAPIApp ユニットの後にこのユニットがくると，Application は誤った型のオブジェクトに初期化されます。


The structure of a Web server application
The structure of a Web server application1120017

Section topics 	参照

Web アプリケーションは HTTP リクエストメッセージを受信すると，HTTP リクエストメッセージを表すTWebRequest オブジェクトを作成し，応答するために TWebResponse オブジェクトを作成します。これらのオブジェクトは Web ディスパッチャ（Web モジュールまたは TWebDispatcher コンポーネント）に渡されます。

Web ディスパッチャは Delphi Web サーバーアプリケーションの処理の流れを制御します。ディスパッチャは， HTTP リクエストメッセージの種類ごとに処理方法を規定している動作項目（TWebActionItem）の集合を保持しています。ディスパッチャは HTTP リクエストメッセージごとにその処理に適した動作項目を特定し，その動作項目のイベントハンドラを起動して，要求された動作やレスポンスメッセージの作成を動作項目によってできるようにします。詳細については，「Web ディスパッチャ」を参照してください。

サーバーアプリケーションの構造

動作項目のイベントハンドラのコードは，どのリクエスト情報にもそれが TWebRequest オブジェクトのプロパティであるものとしてアクセスします。専用のコンテンツプロデューサコンポーネント（TPageProducer や TDataSetTableProducer など）を使うと，動作項目は HTML カスタムコードやその他の MIME コンテンツを動的に作成できます。コンテンツプロデューサは，ほかのコンテンツプロデューサや THTMLTagAttributes の下位オブジェクトを使って，動作項目がレスポンスメッセージのコンテンツを簡単に作成できるようにします。動作項目のイベントハンドラはこのコンテンツを使って，リクエストメッセージを完成させます。詳細については，「レスポンスメッセージのコンテンツの生成」を参照してください。

すべての動作項目が TWebResponse オブジェクトを完全なものにしてレスポンスを完成させると，ディスパッチャはこの結果を Web アプリケーションに返します。アプリケーションはこのレスポンスを Web サーバーを経由してクライアントに送信します。


The Web dispatcher
The Web dispatcher1120018

Section topics 	参照

Web モジュールを使う場合，Web モジュールは Web ディスパッチャとして機能します。既存のデータモジュールを使う場合は，そのデータモジュールにディスパッチャコンポーネントを 1 つ追加しなければなりません。ディスパッチャは，リクエストメッセージの種類ごとに処理方法を規定している動作項目の集合を保持しています。ディスパッチャは，Web アプリケーションからリクエストオブジェクトとレスポンスオブジェクトを受け取ると，そのリクエストに応答するため 1 つまたは複数の動作項目を選択します。


Adding actions to the dispatcher
Adding actions to the dispatcher1120019

Section topics 	参照

ディスパッチャの Actions プロパティで省略記号をクリックすると，オブジェクトインスペクタからプロパティを編集するためのエディタを開くことができます。［追加(A)］ボタンをクリックすることにより，プロパティを編集するためのエディタに動作を追加できます。

異なるリクエストメソッドまたはターゲット URI に応答するには，ディスパッチャに動作を追加します。動作項目を設定するにはいくつもの方法があります。リクエストを前処理する動作項目を最初に設定し，最後にデフォルト動作（レスポンスが完全かどうか確認してからレスポンスを送信するかエラーコードを返します）を設定できます。リクエストの種類ごとに別々の動作項目を追加し，動作項目ごとにリクエストを完全に処理することもできます。

動作項目については，「動作項目」を参照してください。


Dispatching request messages
Dispatching request messages1120020

Section topics 	参照

ディスパッチャは，クライアントリクエストを受信すると，BeforeDispatch イベントを生成します。これにより，アプリケーションはリクエストメッセージを前処理してから，動作項目を使って処理できます。

BeforeDispatch イベントを生成した後，ディスパッチャは動作項目リストで HTTP リクエストメッセージのターゲット URL に対応するものを探し，指定されたサービスをリクエストメッセージのメソッドとして提供できることを示します。これは，TWebRequest オブジェクトの PathInfo プロパティと MethodType プロパティを，動作項目の同名のプロパティと比較すればできます。

ディスパッチャは，適切な動作項目を見つけると，その動作項目の OnAction イベントハンドラを起動します。OnAction イベントハンドラはリクエストを完全に処理することも，部分的に処理してほかの動作項目に残りの処理を任せることも，リクエストのすべての処理をほかの動作項目に任せることもできます。OnAction イベントハンドラは Handled パラメータを False に設定して，ディスパッチャがリクエストをほかの動作項目に引き続き渡さなければならないことを知らせます。

ディスパッチャがすべての動作項目を確認し終わってもリクエストメッセージの処理が完了していない場合，ディスパッチャはデフォルト動作項目を呼び出します。デフォルト動作項目はターゲット URL にもリクエストのメソッドにも対応している必要はありません。

ディスパッチャが動作項目リストの最後（デフォルト動作項目があればそれも含みます）まできても起動されている動作がないと，サーバーには何も返されません。サーバーはクライアントへの接続を切断するだけです。

動作項目がリクエストを処理すると，ディスパッチャは AfterDispatch イベントを生成します。これにより，アプリケーションは生成されたレスポンスを確認して最後の変更ができます。


Action items
Action items1120021

Section topics 	参照

動作項目はそれぞれ，特定の種類のリクエストメッセージに応じて決まった処理を実行します。動作項目はリクエストに完全に応答することも，部分的に応答して残りをほかの動作項目に任せることもできます。動作項目はリクエストに対する HTTP レスポンスメッセージを送信することも，レスポンスを部分的に設定するだけにして残りの処理をほかの動作項目に任せることもできます。動作項目が処理したレスポンスを送信しないと，Web サーバーアプリケーションがそのレスポンスメッセージを送信します。


Specifying action item properties
Specifying action item properties1120022

Section topics 	参照

動作項目のプロパティにより，ディスパッチャが HTTP リクエストメッセージを処理するためにその動作項目を選択するかどうかが決まります。動作項目のプロパティを設定するには，まず動作エディタを起動してから，オブジェクトインスペクタでディスパッチャの Actions プロパティを選択し，省略記号をクリックします。動作エディタで動作を選択すると，オブジェクトインスペクタでそのプロパティを変更できます。

The target URL1120023

ディスパッチャは動作項目の PathInfo プロパティとリクエストメッセージのターゲット URL のパス部分を比較します。このプロパティの値は，動作項目が処理できるすべてのリクエストに対応した URL のパス情報部分でなければなりません。たとえば，次の URL があるとします。

http://www.TSite.com/art/gallery.dll/mammals?animal=dog&color=black

/gallery.dll 部分が Web サーバーアプリケーションであると仮定すると，パス情報部分は次のようになります。

/mammals

The request method1120024

動作項目の MethodType プロパティは，その動作項目が処理できるリクエストメッセージの種類を示します。ディスパッチャは動作項目の MethodType プロパティと，リクエストメッセージの MethodType を比較します。次の表に MethodType の値を示します。

値	意味
mtGet	ターゲット URI に関連した情報をレスポンスメッセージに入れて返すことを要求している
mtHead	mtGet リクエストを処理するときと同様にレスポンスのヘッダープロパティを要求しているが，レスポンスのコンテンツは省略する
mtPost	Web アプリケーションに登録すべき情報を提供している
mtPut	ターゲット URI に関連付けられたリソースを，リクエストメッセージのコンテンツによって置き換えることを要求する
mtAny	動作項目がどのリクエストメソッド型（mtGet，mtHead，mtPost）にも対応している
Enabling and disabling action items1120025

動作項目には，その動作項目を使用可能または使用不可にする Enabled プロパティがあります。Enabled を False に設定すると動作項目は使用不可になり，ディスパッチャはリクエストを処理する動作項目を探すときこの動作項目を対象外とみなします。

BeforeDispatch イベントハンドラは，ディスパッチャがリクエストメッセージに適した動作項目を探す前に，動作項目の Enabled プロパティを変更してどの動作項目がリクエストを処理すべきかを制御できます。

注意	実行時に動作の Enabled プロパティを変更すると，それ以降のリクエストに対して予想外の結果が生じることがあります。Web サーバーアプリケーションが Web モジュールをキャッシュする DLL の場合，次のリクエストに対する初期状態は再初期化されません。BeforeDispatch を使用すれば，すべての動作項目は初期状態に正しく初期化されます。

Choosing a default action item1120026

デフォルト動作項目にできる動作項目は 1 つだけです。動作項目の Default プロパティを True に設定すると，その動作項目がデフォルト動作項目として選択されます。ある動作項目の Default プロパティを True に設定すると，それまでにデフォルトとして選択されていた動作項目があれば，その動作項目の Default プロパティは False に設定されます。

ディスパッチャは，リクエストを処理する動作項目を選択するため動作項目リストを検索するとき，デフォルト動作項目の名前を格納します。ディスパッチャが動作項目リストの最後まできてもリクエストの処理が完了していない場合，ディスパッチャはデフォルト動作項目の OnAction イベントハンドラを呼び出します。

動作項目がデフォルト動作項目であり，リクエストが処理されていない場合，ディスパッチャはその動作項目のイベントハンドラを呼び出します。ディスパッチャはデフォルト動作項目の PathInfo や MethodType の確認は行わず，Enabled プロパティでさえも確認しません。このため，デフォルト動作項目の Enabled プロパティを False にして，最後にならないとデフォルト動作項目が呼び出されないようにすることができます。

デフォルト動作項目は，URI または MethodType が無効であることを示すエラーコードを返すだけの場合も含めて，あらゆるリクエストを処理する準備をしておかなければなりません。デフォルト動作項目がリクエストを処理しないと，Web クライアントにレスポンスが送信されません。

注意	実行時に動作の Default プロパティを変更すると，現在のリクエストに対して予想外の結果が生じることがあります。すでに起動済みの動作項目の Default プロパティを True に設定すると，その動作は再評価されず，動作項目リストの最後まできてもディスパッチャはその動作を起動しません。


Responding to request messages with action items
Responding to request messages with action items1120027

Section topics 	参照

動作項目は，その OnAction イベントハンドラでリクエストメッセージに応答します。Web サーバーアプリケーションの実際の動作はイベントハンドラで処理されます。OnAction イベントハンドラには，HTTP リクエストメッセージを表す TWebRequest オブジェクトと，すべてのレスポンス情報を書き込むための TWebResponseオブジェクトが渡されます。

OnAction イベントハンドラでは，どの Delphi オブジェクトやランタイムライブラリメソッドを使ってでもリクエストメッセージに応答できます。データベースへのアクセス，計算，HTML ドキュメントの作成または選択などができます。Delphi では各種のコンテンツプロデューサオブジェクトを使って HTML ページを作成し，レスポンスメッセージのコンテンツにできます。

Sending the response1120028

動作項目は，TWebResponse オブジェクトのメソッドを使って Web クライアントにレスポンスを送り返すことができます。ただし，動作項目がクライアントにレスポンスを送信しない場合は，最後にリクエストに対処した動作項目でそのリクエストが処理されたことが示されていれば，Web サーバーアプリケーションがレスポンスを送信します。

Using multiple action items1120029

リクエストに対して 1 つの OnAction イベントハンドラで応答することも，複数の動作項目で処理を分担して応答することもできます。各動作項目は担当の処理を完了した後で OnAction イベントハンドラの Handled パラメータを False に設定して，レスポンスの処理が完了したわけではないことをディスパッチャに知らせることができます。

複数の動作項目でリクエストメッセージへのレスポンス処理を分担し，動作項目ごとに Handled パラメータを False に設定してほかの動作項目が処理を継続できるようにする場合，デフォルト動作項目の Handled パラメータは True のままにしておいてください。そうしないと，レスポンスが Web クライアントに送信されません。

複数の動作項目で処理を分担する場合，デフォルト動作項目の OnAction イベントハンドラまたはディスパッチャの AfterDispatch イベントハンドラが，すべての処理が実行されたかどうか確認し，実行されていなければ該当するエラーコードを返さなければなりません。


Accessing client request information
Accessing client request information1120030

Section topics 	参照

Web サーバーアプリケーションが HTTP リクエストメッセージを受信すると，クライアントリクエストのパラメータが TWebRequest オブジェクトのプロパティにロードされます。NSAPI アプリケーションと ISAPI アプリケーションの場合，リクエストメッセージは TISAPIRequest オブジェクトによってカプセル化されます。コンソール CGI アプリケーションは TCGIRequest オブジェクトを使い，Windows CGI アプリケーションは TWinCGIRequest オブジェクトを使います。

リクエストオブジェクトのプロパティは読み出し専用です。これらのプロパティを使うと，クライアントリクエストで使えるすべての情報を収集できます。


Properties that contain request header information
Properties that contain request header information1120031

Section topics 	参照

リクエストオブジェクトのほとんどのプロパティには，HTTP リクエストヘッダーから受け取ったリクエストに関する情報が入っています。すべてのリクエストがこれらのどのプロパティにも値を提供するわけではありません。また，リクエストによっては，リクエストオブジェクトのプロパティで指定されていないヘッダー項目が含まれていることがあります。特に，HTTP 標準の継続的な改訂に伴ってこのようなことが起こります。リクエストオブジェクトのプロパティとして表示されていないリクエストヘッダー項目の値を取得するには，GetFieldByName メソッドを使います。

Properties that identify the target1120032

リクエストメッセージの完全なターゲットは，URL プロパティによって指定されます。これは，通常はプロトコル（HTTP），Host（サーバーシステム），ScriptName（サーバーアプリケーション），PathInfo（ホスト上の位置），Query から構成されます。これらの要素はそれぞれのプロパティで指定されています。ディスパッチャは，動作項目をリクエストメッセージに対応付けるときに PathInfo 部を使います。プロトコルは必ず HTTP です。Host と ScriptName は Web サーバーアプリケーションを識別します。Query は，必要な情報の詳細を指定するのにリクエストで使うことがあります。この値も QueryFields プロパティとして解析されます。

Properties that identify the Web client1120033

リクエストには，リクエストの送信元情報を示すプロパティもいくつか含まれています。たとえば，送信側の電子メールアドレス（From プロパティ），メッセージの送信元 URI（Referer プロパティまたは RemoteHost プロパティ）などがあります。リクエストにコンテンツが含まれており，そのコンテンツがリクエストと同じ URI からのものでない場合，コンテンツのソースが DerivedFrom プロパティによって示されます。クライアントの IP アドレス（RemoteAddr プロパティ）やリクエストを送信したアプリケーションの名前やバージョン（UserAgent プロパティ）も確認できます。

Properties that identify the purpose of the request1120034

Method プロパティは，リクエストメッセージがサーバーアプリケーションに要求している動作を示す文字列です。次の表に HTTP 1.1 標準で定義しているメソッドを示します。

値	メッセージのリクエスト
OPTIONS	利用可能な通信オプションについての情報
GET	URL プロパティで指定された情報
HEAD	同等の GET メッセージからのヘッダー情報。レスポンスのコンテンツは不要
POST	該当する場合，Content プロパティのデータをサーバーアプリケーションが登録する
PUT	URL プロパティで指定されたリソースを Content プロパティのデータでサーバーアプリケーションが置換する
DELETE	URL プロパティで指定されたリソースをサーバーアプリケーションが削除または非表示にする
TRACE	リクエストの受信を確認するためループバックをサーバーアプリケーションが送信する
Method プロパティは，Web クライアントがサーバーに要求するその他のメソッドを示すことができます。

Web サーバーアプリケーションは Method のすべての値に応答する必要はありません。ただし，HTTP 標準では，Web サーバーアプリケーションが GET リクエストと HEAD リクエストのどちらも処理することを規定しています。

MethodType プロパティは，Method の値が GET（mtGet），HEAD（mtHead），POST（mtPost），Put（mtPut）その他の文字列（mtAny）のどれであるかを示します。ディスパッチャは MethodType プロパティの値と，各動作項目の MethodType を照合します。

Properties that describe the expected response1120035

Accept プロパティは，Web クライアントがレスポンスメッセージのコンテンツとして受け付けるメディアの種類を指定します。IfModifiedSince プロパティは，最近変更された情報だけをクライアントが必要としているかどうかを示します。Cookie プロパティは，レスポンスを変更できる状態情報を示します。

Properties that describe the content1120036

ほとんどのリクエストは，情報を求めるものであるため，コンテンツは含まれていません。ただし，POST リクエストのように，Web サーバーアプリケーションが使うと思われるコンテンツを提供するものもあります。コンテンツのメディアの種類は ContentType プロパティで指定され，長さは  ContentLength プロパティで指定されます。データ圧縮などのためにメッセージのコンテンツが符号化されている場合，この情報は ContentEncoding プロパティにあります。コンテンツを作成したアプリケーションの名前とバージョン番号は ContentVersion プロパティで指定されています。Title プロパティもコンテンツに関する情報を提供することがあります。


The content of HTTP request messages
The content of HTTP request messages1120037

Section topics 	参照

リクエストメッセージのによっては，ヘッダー項目のほかに，Web サーバーアプリケーションがなんらかの方法で処理しなければならないコンテンツ部分が含まれていることがあります。たとえば，POST リクエストには，Web サーバーアプリケーションが保持するデータベースに追加しなければならない情報が入っています。

コンテンツが未処理であることを示す値は Content プロパティで示されます。コンテンツを解析して項目ごとにアンド記号（&）で区切ることができる場合，ContentFields プロパティで解析バージョンが指定されています。


Creating HTTP response messages
Creating HTTP response messages1120038

Section topics 	参照

Web サーバーアプリケーションが受信した HTTP リクエストメッセージ用に TWebRequest オブジェクトを作成するときは，返信するレスポンスメッセージを表す TWebResponse オブジェクトも作成します。NSAPI アプリケーションと ISAPI アプリケーションでは，レスポンスメッセージが TISAPIResponse オブジェクトによってカプセル化されています。コンソール CGI アプリケーションは TCGIResponse オブジェクトを使い，Windows CGI アプリケーションは TWinCGIResponse オブジェクトを使います。

OnAction イベントハンドラは Web クライアントリクエストへのレスポンスを生成する場合，レスポンスオブジェクトのプロパティを指定します。単にエラーコードを返すか，リクエストをほかの URI にリダイレクトするだけのこともあります。イベントハンドラがほかのソースから情報を取得し，それを完全な形式に組み立てなければならない複雑な計算が含まれていることもあります。要求された動作が実行されたことを伝えるだけの場合も含めて，ほとんどのリクエストメッセージではレスポンスが必要です。


Filling in the response header
Filling in the response header1120039

Section topics 	参照

TWebResponse オブジェクトのほとんどのプロパティは，Web クライアントに返信する HTTP レスポンスメッセージのヘッダー情報を表します。すべてのレスポンスメッセージでどのヘッダープロパティにも値を指定する必要があるわけではありません。設定が必要なプロパティは，リクエストの性質やレスポンスの状態によって異なります。

Indicating the response status1120040

レスポンスメッセージには，レスポンスの状態を示すステータスコードが入っていなければなりません。ステータスコードを指定するには，StatusCode プロパティを設定します。HTTP 標準では，既定の意味を持つ標準のステータスコードがいくつも定義されています。未使用の有効な値を使えば自分でステータスコードを定義することもできます。

ステータスコードは以下のような 3 桁の数字であり，最上位の桁がレスポンスクラスを示します。

1xx: Informational（リクエストが受信されたが処理は完了していない）

2xx: Success（リクエストが受信され，認識され，受け付けられた）

3xx: Redirection（リクエストを完了するにはクライアントの動作がさらに必要である）

4xx: Client Error（リクエストを認識できないか処理できない）

5xx: Server Error（リクエストは有効だが，サーバーが処理できなかった）

ステータスコードと一緒に表示される文字列はステータスコードの意味を示しています。これは，ReasonString プロパティによって指定されます。定義済みのステータスコードの場合は ReasonString プロパティを設定する必要がありません。自分でステータスコードを定義した場合は，ReasonString プロパティも設定する必要があります。

Indicating the need for client action1120041

ステータスコードが 300～399 の場合，クライアントがさらに動作を実行しなければ Web サーバーアプリケーションはリクエストの処理を完了できません。クライアントを別の URI にリダイレクトしなければならないか，リクエストを処理する新しい URI が作成されたことを示さなければならない場合は，Location プロパティを設定します。クライアントがパスワードを入力しないと処理を続けられない場合は，WWWAuthenticate プロパティを設定します。

Describing the server application1120042

レスポンスヘッダーのプロパティの中には，Web サーバーアプリケーションの機能を記述するものがあります。Allow プロパティはアプリケーションが応答できるメソッドを指定します。Server プロパティは，レスポンスの生成に使うアプリケーションの名前とバージョン番号を指定します。

Describing the content1120043

プロパティの中にはレスポンスのコンテンツを記述するものがあります。ContentType はレスポンスのメディアの種類を指定し，ContentVersion はそのメディアの種類のバージョン番号を指定します。ContentLength はレスポンスの長さを指定します。データ圧縮などのためにコンテンツが符号化されている場合，このコンテンツはContentEncoding プロパティで指定されます。コンテンツが別の URI のものである場合，このコンテンツは DerivedFrom プロパティで指定されます。コンテンツの値に期間の制限がある場合，LastModified プロパティと Expires プロパティが値がまだ有効かどうかを示します。SetCookie プロパティと Title プロパティはコンテンツの状態情報と記述情報を指定できます。


Setting the response content
Setting the response content1120044

Section topics 	参照

リクエストによっては，リクエストメッセージへのレスポンスがレスポンスのヘッダープロパティに完全に含まれている場合があります。しかし，ほとんどの場合は，イベントハンドラが最終的な動作としてレスポンスメッセージになんらかのコンテンツを割り当てなければなりません。このコンテンツはファイルに格納された静的情報のことも，OnAction イベントハンドラが動的に作成する情報のこともあります。

レスポンスメッセージのコンテンツは，Content プロパティまたは ContentStream プロパティを使って設定できます。

Content プロパティは Delphi 文字列です。Delphi 文字列はテキスト値に限られるわけではありません。したがって，Content プロパティの値は，HTML コマンド文字列，グラフィックコンテンツ（ビットストリームなど），その他の種類の MIME コンテンツのどれでもかまいません。

レスポンスメッセージのコンテンツをストリームから読み出せる場合は ContentStream プロパティを使います。たとえば，レスポンスメッセージがファイルの内容を送信しなければならない場合は，ContentStream プロパティの TFileStream オブジェクトを使います。Content プロパティの場合と同様に，ContentStream は HTML コマンド文字列かその他の種類の MIME コンテンツを示さなければなりません。ContentStream プロパティを使う場合は，自分でストリームを解放しないでください。Web レスポンスオブジェクトが自動的に解放します。

メモ	ContentStream プロパティの値が nil 以外の場合，Content プロパティは無視されます。


Sending the response
Sending the response1120045

Section topics 	参照

リクエストメッセージに対してこれ以上処理が必要ないと判断したら，OnAction イベントハンドラからレスポンスを直接送信できます。TWebResponse オブジェクトには，レスポンスの送信用に SendResponse と  SendRedirect の 2 つのメソッドがあります。指定したコンテンツと TWebResponse オブジェクトのすべてのヘッダープロパティを使ってレスポンスを送信するには，SendResponse を呼び出します。Web クライアントを別の URI にリダイレクトするだけなら，SendRedirect メソッドを使う方が効率的です。

どのイベントハンドラもレスポンスを送信しないときには，ディスパッチャの終了後に Web アプリケーションオブジェクトがレスポンスを送信します。ただし，レスポンスを処理したことを示している動作項目がない場合，アプリケーションはレスポンスを送信せずに Web クライアントへの接続を切断します。


Generating the content of response messages
Generating the content of response messages1120046

Section topics 	参照

Delphi には，OnAction イベントハンドラで HTTP レスポンスメッセージ用のコンテンツを作成するのに役立つオブジェクトがいくつも用意されています。これらのオブジェクトを使うと，ファイル内に保存するか Web クライアントに直接返送する HTML コマンド文字列を生成できます。TCustomContentProducer またはその下位オブジェクトから自分でコンテンツプロデューサを作成することもできます。

TCustomContentProducer にはどの種類の MIME でも HTTP レスポンスメッセージのコンテンツとして作成できる汎用インターフェースがあります。また 2 つの下位オブジェクト TDSTableProducer と  TCustomPageProducer があります。TDSTableProducer はデータセットの情報を使って HTML コマンドを作成します。TDSTableProducer の下位オブジェクトについては，「レスポンスでのデータベース情報の使い方」を参照してください。

TCustomPageProducer は TPageProducer の基本クラスです。ページプロデューサは HTML ドキュメントをスキャンし，カスタマイズした HTML コードに置換する特殊なタグを探します。


Using page producer components
Using page producer components1120047

Section topics 	参照

TPageProducer コンポーネントは  HTML テンプレートを取り出し，特殊な  HTML透過タグをカスタマイズした HTML コードに置換してそのテンプレートを変換します。HTTP リクエストメッセージへのレスポンスを生成しなければならない場合，ページプロデューサが指定した標準のレスポンステンプレートセットを格納できます。ページプロデューサを連鎖させると，HTML 透過タグの適切な置換を連続的に行うことにより，1 つの HTML ドキュメントを繰り返し構築し直すことができます。

HTML templates1120048

HTML テンプレートは一連の HTML コマンドと HTML 透過タグで構成されます。次に HTML 透過タグの形式を示します。

<#TagName Param1=Value1 Param2=Value2 ...>

不等号カッコ（< と >）はタグのスコープ全体を定義します。開き不等号カッコの直後にはスペースなしで番号記号（#）が続きます。ページプロデューサは番号記号の後ろの文字列を HTML 透過タグとして認識します。タグ名は番号記号の直後にスペースなしで続きます。タグ名は任意の有効な Object Pascal 識別子であり，タグが表す変換型を識別します。

Delphi には TTag データ型の値に関連付けられたいくつかの定義済みのタグ名があります。

タグ名	TTag 値	タグの変換先
Link	tgLink	ハイパーテキストリンク。<A> タグと </A> タグで囲まれた HTML シーケンスに変換される
Image	tgImage	グラフィックイメージ。HTML <IMG> タグに変換される
Table	tgTable.	HTML テーブル。<TABLE> タグと </TABLE> タグで囲まれた HTML シーケンスに変換される
ImageMap	tgImageMap	ホットゾーンが関連付けられたグラフィックイメージ。<MAP> タグと </MAP> タグで囲まれた HTML シーケンスに変換される
Object	tgObject	埋め込まれた ActiveX オブジェクト。<OBJECT> タグと </OBJECT> タグで囲まれた HTML シーケンスに変換される
Embed	tgEmbed	Netscape 準拠のアドイン DLL。<EMBED> タグと </EMBED> タグで囲まれた HTML シーケンスに変換される
その他のタグ名はすべて tgCustom に関連付けられます。ページプロデューサは，定義済みのタグ名に対する組み込みの処理を供給していません。定義済みのタグは，単にアプリケーションが変換処理をより一般的なタスク構成に組み入れるのを支援するために提供されています。

メモ	定義済みのタグ名は大文字と小文字を区別します。

HTML 透過タグでは，タグ名の後ろに変換の詳細を指定するパラメータを入れることもできます。パラメータの形式は ParamName=Value です。パラメータ名，等号記号（=），値の間にはスペースを入れません。パラメータどうしはスペースで区切ります。

不等号カッコ（< と >）は #TagName 構造を認識しない HTML ブラウザに対してタグを透過にします。

Specifying the HTML template1120049

TPageProducer には，HTML テンプレートを指定する方法がいくつも用意されています。HTMLFile プロパティには，HTML テンプレートが入っているファイルの名前を設定できます。HTMLDoc プロパティには，HTML テンプレートが入っている TStrings オブジェクトを設定できます。HTMLFile プロパティまたは HTMLDoc プロパティを使ってテンプレートを指定する場合は，Content メソッドを呼び出して変換済みの HTMLコマンドを生成できます。

ContentFromString メソッドを呼び出すと，パラメータとして渡される単一の Delphi 文字列で構成されている HTML テンプレートを直接変換できます。また，ContentFromStream メソッドを呼び出すことにより，ストリームから HTML テンプレートを読み出すこともできます。したがって，たとえばすべての HTML テンプレートをデータベースの 1 つのメモ型項目に格納し，ContentFromStream メソッドを使って変換済みの HTML コマンドを取得して，TBlobStream オブジェクトから直接テンプレートを読み出すことができます。

Converting HTML-transparent tags1120050

ページプロデューサのいずれかの Content メソッドを呼び出すと，そのページプロデューサは HTML テンプレートを変換します。Content メソッドは HTML 透過タグを検出すると，OnHTMLTag イベントハンドラを起動します。イベントハンドラは，検出したタグの種類を確認し，そのタグをカスタマイズしたコンテンツに置換するように作成しなければなりません。

Using page producers from an action item1120051

ページプロデューサコンポーネントは一般に，HTMLFile プロパティを使って HTML テンプレートが入っているファイルを指定し，Content メソッドを呼び出してテンプレートを最終的な HTML シーケンスに変換するために使います。

procedure MyActionEventHandler(Sender: TObject; Request: TWebRequest;

Response: TWebResponse; var Handled: Boolean);

begin

PageProducer1.HTMLFile := 'Greeting.html';

Response.Content := PageProducer1.Content;

end;

Greeting.html はこの HTML テンプレートが入っているファイルです。

<HTML>

<HEAD><TITLE>Our brand new web site</TITLE></HEAD>

<BODY>

Hello <#UserName>!	Welcome to our web site.

</BODY>

</HTML>

OnHTMLTagイベントハンドラは実行時に HTML 内のカスタムタグ（<#UserName>）を置換します。

procedure HTMLTagHandler(Sender: TObject;Tag: TTag;

const TagString: String; TagParams: TStrings;

var ReplaceText: String);

begin

if CompareText(TagString,'UserName') = 0 then

ReplaceText := TPageProducer(Sender).Dispatcher.Request.Content;

end;

リクエストメッセージのコンテンツが文字列 Mr. Ed であれば，Response.Content の値は次のようになります。

<HTML>

<HEAD><TITLE>Our brand new web site</TITLE></HEAD>

<BODY>

Hello Mr. Ed!	Welcome to our web site.

</BODY>

</HTML>

TPageProducer オブジェクトの OnHTMLTag イベントを作成していない場合，タグは空文字列に置換されます。

Chaining page producers together1120052

OnHTMLTag イベントハンドラの置換用文字列は，HTTP レスポンスメッセージで使いたい最終的な HTML シーケンスである必要はありません。複数のページプロデューサを使うと，あるページプロデューサの出力を次のページプロデューサの入力にできます。

たとえば，目的のページの月と年を指定するリクエストメッセージに応じて，カレンダーページを返すアプリケーションがあるとします。各カレンダーページにはイメージがあり，その後ろには，前月と翌月の小さなイメージの間に何年の何月かが示されます。最後に実際のカレンダーが続きます。この結果，次の図に示すようになります。

次にテンプレートファイルに格納されるカレンダーの一般的な形式を示します。

<HTML>

<Head></HEAD>

<BODY>

<#MonthlyImage> <#TitleLine><#MainBody>

</BODY>

</HTML>

最初のページプロデューサの OnHTMLTag イベントハンドラは，リクエストメッセージから月と年を探します。この情報とテンプレートファイルを使って，ページプロデューサは次の処理を実行します。

<#MonthlyImage> を <#Image Month=January Year=1997> に置換する

<#TitleLine> を <#Calendar Month=December Year=1996 Size=Small> January 1997 <#Calendar Month=February Year=1997 Size=Small> に置換する

<#MainBody> を <#Calendar Month=January Year=1997 Size=Large> に置換する

次のページプロデューサの OnHTMLTag イベントハンドラは最初のページプロデューサが作成したコンテンツを使い，<#Image Month=January Year=1997> タグを適切な HTML <IMG> タグに置換します。さらに別のページプロデューサが #Calendar タグを適切な HTML テーブルに置換します。


Using database information in responses
Using database information in responses1120053

Section topics 	参照

HTTP リクエストメッセージへのレスポンスには，データベースの情報を入れることができます。Delphi の特殊なコンテンツプロデューサを使うと，HTML テーブルでデータベースのレコードを表す HTML を生成できます。


Adding a session to the Web module
Adding a session to the Web module1120054

Section topics 	参照

コンソール CGI アプリケーションと Win-CGI アプリケーションはどちらも HTTP リクエストメッセージに応答して起動されます。これらの種類のアプリケーションでデータベースを操作する場合，デフォルトセッションを使ってデータベースの接続を管理できます。これは，リクエストメッセージごとにアプリケーションインスタンスが異なるからです。アプリケーションインスタンスごとにデフォルトセッションは異なります。

ただし， ISAPI アプリケーションまたは NSAPI アプリケーションを作成すると，各リクエストメッセージ は 1 つのアプリケーションインスタンスの個別のスレッドで処理されます。異なるスレッドからのデータベース接続が互いに妨害し合わないようにするには，スレッドごとに固有のセッションを割り当てなければなりません。

ISAPI アプリケーションまたは NSAPI アプリケーションの各リクエストメッセージは新しいスレッドを生成します。そのスレッドの Web モジュールは実行時に動的に生成されます。Web モジュールが入っているスレッドのデータベース接続を処理するには，Web モジュールに TSession オブジェクトを追加します。

Web モジュールの個々のインスタンスは，実行時にスレッドごとに生成されます。これらのモジュールのそれぞれに，セッションオブジェクトが入っています。これらのセッションにはそれぞれ別々の名前が付いていなければならないので，各リクエストメッセージを処理するスレッドは互いのデータベース接続を妨害しません。各モジュールのセッションオブジェクトが動的にそれぞれユニークな名前を生成するようにするには，セッションオブジェクトの AutoSession プロパティを設定します。各セッションオブジェクトは自身にユニークな名前を動的に生成し，モジュール内のすべてのデータセットの AutoSessionName プロパティがそのユニークな名前を参照するようにします。これにより，リクエストスレッドごとのデータベースとの対話はほかのどのリクエストメッセージも妨害せずに処理できます。詳細については，「データベースセッションの管理」を参照してください。


Representing a dataset in HTML
Representing a dataset in HTML1120055

Section topics 	参照

TDSTableProducer の下位オブジェクトは，データセットの情報を HTML テーブルの形式に設定します。テーブルの形式をカスタマイズするには，そのテーブルの色，境界，分割線の太さなどのプロパティを指定します。

Specifying the table attributes1120056

TDSTableProducer オブジェクトは THTMLTableAttributes オブジェクトを使って，データセットのレコードを表示する HTML テーブルの表示形式を指定します。THTMLTableAttributes オブジェクトには，HTML ドキュメント内のテーブルの幅や間隔，背景色，境界線の太さ，セルのパディング，セルの間隔などを指定するプロパティが含まれています。これらのプロパティは，どれも TDSTableProducer オブジェクトが作成する HTML <TABLE> タグのオプションとして設定されています。

これらのプロパティは，設計時にオブジェクトインスペクタを使って指定します。オブジェクトインスペクタでテーブルプロデューサオブジェクトを選択し，THTMLTableAttributes オブジェクの表示プロパティにアクセスできるように TableAttributes プロパティを拡張します。

これらのプロパティは，実行時にプログラムで指定することもできます。

Specifying the row attributes1120057

テーブル属性と同様に，データを表示するテーブルの行でセルの位置合わせや背景色を指定できます。RowAttributes プロパティは THTMLTableRowAttributes オブジェクトです。

これらのプロパティは，設計時にオブジェクトインスペクタを使って RowAttributes プロパティを展開して指定します。これらのプロパティは実行時にプログラムで指定することもできます。

HTML テーブルでの行数も，MaxRows プロパティを設定して調整できます。

Specifying the columns1120058

テーブルに入れるデータセットが設計時にわかっている場合は，列エディタを使って列の項目結合や表示属性をカスタマイズできます。まず，テーブルプロデューサコンポーネントを選択して右クリックします。次に，コンテキストメニューで［列エディタ］を選択します。これにより，テーブルで列の追加，削除，再配置ができます。個々の列の項目結合や表示プロパティは，列エディタで選択すれば，オブジェクトインスペクタで設定できます。

HTTP リクエストメッセージからデータセットの名前を取り出す場合，設計時に列エディタで項目を結合することはできません。ただし，適切な THTMLTableColumn オブジェクトを設定し，Columns プロパティのメソッドを使ってそれらのオブジェクトをテーブルに追加すれば，実行時にプログラムで列を設定できます。Columns プロパティを正しく設定しないと，データセットの項目に一致するデフォルトの列セットが作成され，特殊な表示特性は指定されません。

Embedding tables in HTML documents1120059

TDSTableProducer コンポーネントの Header プロパティと Footer プロパティを使うと，データセットを表す HTML テーブルを大きなドキュメントに埋め込むことができます。テーブルより前にくるすべてのものを指定するには Header を使い，テーブルの後にくるすべてのものを指定するには Footer を使います。

別のコンテンツプロデューサを使って Header プロパティと Footer プロパティの値を作成することもできます。

テーブルを大きなドキュメントに埋め込む場合，テーブルにキャプションを追加することもできます。テーブルにキャプションを追加するには，Caption プロパティと CaptionAlignment プロパティを使います。


Using TDataSetTableProducer
Using TDataSetTableProducer1120060

Section topics 	参照

TDataSetTableProducer はデータセットの HTML テーブルを作成する TDSTableProducer コンポーネントです。表示したいレコードが入っているデータセットを指定するには，TDataSetTableProducer の DataSet プロパティを設定します。従来の Delphi アプリケーションではほとんどのデータベース対応オブジェクトで DataSource プロパティを設定しますが，TDataSetTableProducer については DataSource プロパティは設定しません。これは，TDataSetTableProducer が自分のデータソースを内部で生成するからです。HTML イメージとして，TDataSetTableProducer が作成するテーブルでは，ほかのオブジェクトに対してレコードが通用するようにしておく必要はありません。

Web アプリケーションが必ず同じデータセットのレコードを表示する場合は，DataSet の値は設計時に設定できます。データセットが HTTP リクエストメッセージの情報に基づいている場合は，実行時に DataSet プロパティを設定しなければなりません。


Using TQueryTableProducer
Using TQueryTableProducer1120061

Section topics 	参照

問い合わせの結果を表示する HTML テーブルを作成できます。この場合，問い合わせのパラメータは HTTP リクエストメッセージから取り出します。これらのパラメータを TQueryTableProducer コンポーネントの Query プロパティとして使う TQuery オブジェクトを指定します。

リクエストメッセージが GET リクエストの場合，問い合わせのパラメータは HTTP リクエストメッセージのターゲットとして指定された URL の Query 項目から取り出します。リクエストメッセージが POST リクエストの場合，問い合わせのパラメータはリクエストメッセージのコンテンツから取り出します。

TQueryTableProducer の Content メソッドを呼び出すと，TWebRequest オブジェクトで見つけたパラメータを使って問い合わせが実行されます。次に，結果として生成されたデータセットのレコードを表示できるように HTML テーブルの形式を設定します。

すべての TDSTableProducer コンポーネントの場合と同様に，HTML テーブルの表示プロパティと列結合のカスタマイズや，大きな HTML ドキュメントへのテーブルの埋め込みができます。.


Debugging server applications
Debugging server applications1120062

Section topics 	参照

Web サーバーアプリケーションのデバッグについては，固有の問題があります。Web サーバーアプリケーションが Web サーバーからのメッセージに応じて実行されるからです。IDE からはアプリケーションを起動することはできません。こうすると Web サーバーがループから除外され，アプリケーションは待ち受けているリクエストメッセージを見つけることができなくなるからです。この節では，Web サーバーアプリケーションをデバッグする方法について説明します。


Debugging ISAPI and NSAPI applications
Debugging ISAPI and NSAPI applications1120063

Section topics 	参照

ISAPI アプリケーションと NSAPI アプリケーションは実際にはエントリポイントが定義済みである DLL です。Web サーバーは，これらのエントリポイントを呼び出して，リクエストメッセージをアプリケーションに渡します。サーバーを起動するアプリケーションの実行パラメータは開発者が設定しなければなりません。ブレークポイントを設定して，サーバーがリクエストメッセージを DLL に渡したら，ブレークポイントのいずれかに達して通常どおりにデバッグできるようにします。

メモ	アプリケーションの実行時引数を使って Web サーバーを起動するときには，そのサーバーがまだ実行されていないことを確認してください。

Debugging under Windows NT1120064

Windows NT では，DLL をデバッグする適切なユーザー権利を持っていなければなりません。 NT ユーザーマネージャで権利を認定する手順は次のとおりです。

1.	［原則(P)｜ユーザーの権利(U)］を選択します。

2.	［高度なユーザー権利の表示(S)］をチェックします。

3.	［権利(T)］リストで［オペレーティングシステムの一部として機能］を選択します。

4.	［この権利を与えられたアカウント(G)］リストに自分の名前を追加します。

Debugging with a Microsoft IIS server1120065

Microsoft IIS サーバーを使って Web サーバーアプリケーションをデバッグするには，［Run｜Parameter］を選択して，アプリケーションの実行パラメータを次のように設定します。

Host Application: c:\winnt\system32\inetsrv\inetinfo.exe

Run Parameters:	-e w3svc

これにより IIS サーバーが起動し，ISAPI DLL のデバッグが可能になります。

メモ	inetinfo.exe へのディレクトリパスはこの例とは異なる場合があります。

Debugging with a Windows 95 Personal Web Server1120066

Personal Web サーバーを使って Web サーバーアプリケーションをデバッグするには，アプリケーションの実行パラメータを次のように設定します。

Host Application: c:\Program Files\websvc\system\inetsw95.exe

Run Parameters:	-w3svc

これにより Personal Web サーバーが起動し，ISAPI DLL のデバッグが可能になります。

メモ	inetsw95.exe へのディレクトリパスはこの例とは異なる場合があります。

Debugging with Netscape Server Version 2.01120067

Netscape サーバーで Web サーバーアプリケーションを実行するには，その前に環境設定を一部変更しなければなりません。

まず ISAPITER.DLL ファイル（Delphi 3\Bin にあります）を C:\Netscape\Server\Nsapi\Examples ディレクトリにコピーします。実際のディレクトリパスはこれとは異なる場合があります。

次に，C:\Netscape\Server\Httpd-<servername>\Config ディレクトリにあるサーバー環境設定ファイルを次のように変更します。

1.	OBJ.CONF ファイルに次の行を挿入します。

Init funcs="handle-isapi,check-isapi,log-isapi" fn="load-modules"

shlib="c:/netscape/server/nsapi/examples/ISAPIter.dll"

これは次の行の後ろに挿入してください。

Init fn=load-types mime-types=mime.types

2.	OBJ.CONF の <Object name=default> セクションに次の行を挿入します。

NameTrans from="/scripts" fn="pfx2dir" dir="C:/Netscape/Server/docs/scripts"

name="isapi"

これは次の行の前に挿入してください。

NameTrans fn=document-root root="C:/Netscape/Server/docs"

3.	OBJ.CONF の最後に次のセクションを追加します。

<Object name="isapi">

PathCheck fn="check-isapi"

ObjectType fn="force-type" type="magnus-internal/isapi"

Service fn="handle-isapi"

</Object>

4.	MIME.TYPES ファイルの最後に次の行を追加します。

type=magnus-internal/isapi exts=dll

これがファイルの最終行になります。

メモ	手順 1 と手順 2 ではわかりやすくするため改行を入れてあります。これらの行を実際に環境設定ファイルに入れる場合は，復帰を入力しないでください。

Netscape FastTrack サーバーを使って Web サーバーアプリケーションをデバッグするには，アプリケーションの実行パラメータを次のように設定します。

Host Application: c:\Netscape\server\bin\httpd\httpd.exe

Run Parameters:	c:\Netscape\server\httpd-<servername>\config

これによりサーバーが起動し，環境設定ファイルの場所がサーバーに示されます。


Debugging CGI and Win-CGI applications
Debugging CGI and Win-CGI applications1120068

Section topics 	参照

CGI アプリケーションや Win-CGI アプリケーションのデバッグはもう少し面倒です。アプリケーション自体を Web サーバーが起動しなければならないからです。

Simulating the server1120069

Win-CGI アプリケーションの場合，リクエスト情報が入っている環境設定ファイルを自分で作成してサーバーをシミュレートできます。次に Win-CGI アプリケーションを起動し，クライアント情報が入っているファイルの位置と Win-CGI プログラムがコンテンツを作成するために使うファイルの位置を渡します。これで通常どおりにデバッグできます。

Debugging as a DLL1120070

CGI アプリケーションと Win-CGI アプリケーションを利用する別の方法として，まず ISAPI アプリケーションまたは NSAPI アプリケーションとしてアプリケーションを作成し，デバッグします。円滑に機能したら，アプリケーションを CGI アプリケーションまたは Win-CGI アプリケーションに変換します。

CGI アプリケーションと Win-CGI アプリケーションは，ISAPI アプリケーションや NSAPI アプリケーションより単純です。CGI アプリケーションまたは Win-CGI アプリケーションの各インスタンスが処理しなければならないのは，単一のスレッドだけです。このため，これらのアプリケーションでは，ISAPI アプリケーションや NSAPI アプリケーションでは処理しなければならないマルチスレッド問題が生じません。また，ISAPI アプリケーションや NSAPI アプリケーションでの Webモジュールのキャッシングから生じる問題もありません。

アプリケーションを直接変換するには，プロジェクトの uses 節と exports 節の編集，ライブラリヘッダーの削除，適切な $APPTYPE 指令の追加をしなければなりません。あるいは，新しい CGI アプリケーションまたは Win-CGI アプリケーションを作成し，デバッグ済みのアプリケーションの Web モジュールの内容を新しいアプリケーションの Web モジュールにコピーするという方法もあります。


See also1120071

TISAPIApplication

TISAPIRequest

TISAPIResponse

TCGIApplication

TCGIRequest

TCGIResponse

TWinCGIResponse

TWinCGIRequest

TPageProducer

TCustomPageProducer

TDataSetTableProducer

TQueryTableProducer

TCustomContentProducer

THTMLTableAttributes

THTMLTableCellAttributes

TSession

TDatabase

TTable

TQuery

TStoredProc

TWebDispatcher

TCustomDispatcher

TDSTableProducer


OLE and ActiveX Overview
OLE and ActiveX Overview1111001

Section topics 	参照

この章ではまず，OLE や ActiveX などの技術の土台をなすコンポーネントオブジェクトモデル（COM: Component Object Model）について説明します。さらに COM とその利点の概要のほか，Delphi で COM ベースの技術を使うための基礎情報を示します。OLE と ActiveX を Delphi に実装する方法についての詳細は，後の章を参照してください。OLE オートメーションオブジェクトや ActiveX オブジェクトの作成に照準を合わせて説明しています。


An Overview of COM
An Overview of COM1111002

Section topics 	参照

COM（コンポーネントオブジェクトモデル）は，オブジェクトベースのプログラミング仕様であり，定義済みの一連のルーチン（インターフェースといいます）を通じて堅固なオブジェクトの相互運用を可能にします。COM はソースコード標準ではなくバイナリ標準に従っているため，使われている言語，実行中のプロセス空間，プラットフォームに関係なくオブジェクト間で対話できます。COM オブジェクトの作成とそのインターフェースへのアクセスにはユニークな識別子を使うため，COM オブジェクトの機能拡張，変更，更新を透過に行えます。COM には，COM オブジェクトの基本機能を定義する標準インターフェースセットや，COM オブジェクトの作成と管理を目的としたいくつかの API 関数が入っているライブラリもあります。

COM は拡張性のあるシステムソフトウェアアーキテクチャであり，OLE や ActiveX などのほかの技術の土台をなしています。これらの技術は，その型のオブジェクトの作成と操作のために独自の規則を定義し，独自のライブラリを提供するオペレーティングシステム拡張機能です。COM を土台として使うと，開発者は，自分の規則に従って作成したオブジェクトがほかの COM ベースの技術と対話できるように独自に拡張機能を作成できます。

Delphi には COM，OLE，ActiveX の各アプリケーションの基本要素を作成するときに役立つクラスと支援機能があります。Delphi オブジェクトのフレームワークには，1 つのアプリケーションで使う単純な COM 互換クラスから OLE オートメーションサーバーや ActiveX コントロールに使えるクラスまで各種のクラスが用意されています。Delphi を使って COM ベースのアプリケーションを作成すれば，アプリケーションの内部でインターフェースを使ってソフトウェアの構造を改善したり，システム上のほかの COM ベースの API オブジェクト（Win95 Shell 拡張機能や DirectX マルチメディアサポートなど）と対話できるオブジェクトを作成するなど，広範囲な用途に使えます。

最初に COM アプリケーションと ActiveX アプリケーションの基本要素を簡単に説明し，これらの要素を使うための Delphi クラスとツールを紹介します。基本要素には以下のものがあります。

インターフェース: 用途が明確に定義された一連のメソッドプロトタイプ

COM オブジェクト: COM インターフェースのメソッドを実装する，CoClass というクラスのインスタンス

COM／ActiveX サーバー: COM オブジェクトまたは ActiveX オブジェクトのコードが入っているモジュール（EXE，DLL，OCX のいずれか）

クラスファクトリ: 指定した CoClass から COM オブジェクトを作成できるオブジェクト

タイプライブラリ: COM サーバーまたは ActiveX サーバーの型情報が入っているバイナリシンボルファイル。リソースとして保存されることが多い

図に，単純な COM/ActiveX アプリケーション内でのこれらの基本要素の相互関係を示します。

COM/ActiveX サーバーの基本要素


Interfaces
Interfaces1111003

Section topics 	参照

インターフェースは COM の構成要素です。意味的に関連付けられたルーチンのグループであり，COM オブジェクトが対話するときに使います。インターフェースの規則は以下のとおりです。

Interface methods are abstract1111004

インターフェースは一連のメソッドプロトタイプを持ち，その機能を定義します。このメソッド定義には，パラメータの数や種類，戻り型，予想される動作などが含まれています。メソッドの実装方法は定義されていないので，インターフェースに関しては，実際のメソッドの実装は完全に隠れています。したがって，クラスの実装がインターフェースの定義に適合している限り，インターフェースは十分に多様性があります。つまり，インターフェースへのアクセスと使い方は実装に依存しません。この意味でインターフェースは，抽象メソッドとその使い方についての厳密な定義だけがあるクラスに似ています。抽象クラスと同様に，インターフェース自体はインスタンス化できません。インターフェースを使うには，インターフェースを実装するクラスをインスタンス化しなければなりません。

An interface conforms to a binary standard1111005

すべてのインターフェースメソッドは抽象的なので，インターフェースは仮想テーブルへのポインタとして定義できます。仮想テーブルの各エントリは，インターフェースを実装するクラスで対応するインターフェースメソッドの実装を参照します。インターフェースをポインタとして定義すると，COM オブジェクトへのアクセス用のバイナリ準拠プロトコルを確立できます。このため，オブジェクト上のインターフェース実装へのアクセスは，インターフェース仮想テーブルへのポインタを提供するだけで処理できます。

メモ	この章では「仮想テーブル」という用語を伝統的な意味で使います。COM インターフェースに関するほとんどの文献でこの用語が使われています。わかりやすくいうと，インターフェースと仮想テーブルの関係は，Delphi のクラスに対する VMT（仮想メソッドテーブル）の関係に対応します。

An interface encapsulates specific functionality1111006

インターフェースメソッドは意味的に関連付けられて，特定用途向けの機能を提供します。したがって，インターフェースは通常はその動作に合わせて命名され，前に大文字の I が付けられます。たとえば，IMalloc インターフェースはメモリの割り当て，解放，管理を行います。同様に，IPersist インターフェースは，持続性に関連した標準インターフェース（オブジェクトの状態をストレージ，ストリーム，またはファイルでロードし保存するためのメソッドプロトタイプを提供します）の基本インターフェースです。したがって，インターフェースルーチンを実装するクラスはそのサービスをクライアントに提供できます。クライアントはこのクラスを使うオブジェクトとアプリケーションです。

An interface has a unique identifier1111007

互いに衝突しないようにするため，インターフェースはグローバルユニーク識別子（GUID: globally unique identifier）を使って一意性が保証されています。GUID は特殊な種類のユニバーサルユニーク識別子（UUID: universally unique identifier）です。必ずユニークになる 16 バイト（128 ビット）バイナリ形式の値が使われます。インターフェースの識別に使う GUID はインターフェース識別子（IID: interface identifier）と呼ばれます。インターフェースごとに IID が関連付けられていなければなりません。名前ではなくユニークな値でインターフェースを識別すると，既存のコードを更新するときのバージョン管理問題（同じライブラリやルーチンの旧バージョンとの名前の衝突やベンダーが異なる製品間での名前の衝突により発生）を避けることができます。

メモ	Delphi のウィザードを使うと，GUID は自動的に生成されます。

An interface contract is immutable1111008

インターフェースは，特定の機能が不変であることを保証しています。インターフェースは，そのメソッドと，メソッドの動作および必要な入出力を指定します。一度インターフェースの定義を公開したら変更は認められません。インターフェースの意味またはメソッドを変更するには，新しいインターフェースを定義しなければなりません。ただし，どのバージョンにも名前ではなく IID でアクセスするので，オブジェクトがインターフェースの複数のバージョンをサポートしても問題はありません。

Interfaces inherit basic functionality from their ultimate ancestor1111009

どのインターフェースも IUnknown インターフェースから直接または間接に派生しています。この IUnknown インターフェースには動的問い合わせと存続期間の管理というインターフェースの基本機能があります。この機能は仮想テーブルでの順に QueryInterface，AddRef，Release の 3 つの IUnknown メソッドで確立されます。インターフェースを実装するクラスごとに，3 つの IUnknown メソッドのほか，それ以外の上位インターフェースが宣言したすべてのメソッドと，インターフェース自体が宣言したすべてのメソッドを実装しなければなりません。

QueryInterface により，クライアントは特定のオブジェクトに問い合わせを行い，そのオブジェクトがサポートするインターフェースへのポインタにアクセスできるようになります。QueryInterface は仮想テーブルの最初のエントリなので，メモリを効率的に使ってオブジェクトの機能を確認できます。オブジェクトには動的に問い合わせられるので，QueryInterface はほかの従属オブジェクトを更新するというオーバーヘッドなしで，COM オブジェクトを更新できます。QueryInterface のこの機能についての詳細は，「インターフェースをサポートするクラスの使い方」を参照してください。

各インターフェースの仮想テーブルで 2 番目と 3 番目にあるメソッドは AddRef と  Release です。これらのメソッドは，オブジェクトが自分の存続期間を追跡し，時期がきたら自分を削除できるようにする，単純な参照カウンティングメソッドです。参照カウントがゼロ以外の場合，オブジェクトをメモリ内に保持しなければなりません。参照カウントがゼロになったら，インターフェースの実装はその基礎となるオブジェクトを破棄しても問題はありません。このようにして，これらのメソッドは COM オブジェクトの存続期間を管理できるようにします。

メモ	Delphi が提供するオブジェクトが IUnknown の参照カウントとインターフェース問い合わせのほとんどを管理するので，開発者はこの機能を実装する必要はありません。インターフェースの参照カウントについての詳細は，『Object Pascal 言語ガイド』を参照してください。

さまざまな COM 技術に関連したインターフェースのカテゴリについては，「Delphi でのインターフェースの使い方」を参照してください。それぞれの技術に適合したインターフェースを実装する Delphi CoClass について説明してあります。


COM objects
COM objects1111010

Section topics 	参照

COM オブジェクトは，1 つまたは複数のインターフェースを実装する CoClass クラスからインスタンス化されるオブジェクトです。COM オブジェクトは，その CoClass がサポートする各インターフェースが指定するサービスを提供します。COM オブジェクトが使用されるときには，必ずそのいずれかのインターフェースへのポインタによって参照されます。これにより，COM オブジェクトの以下の 2 つの重要な機能が確立されます。

関数ポインタを経由してだけアクセスが可能なので，COM オブジェクトを外部から操作してもデータを直接変更できない

インターフェース参照はポインタなので，関数ポインタの構造（配列）へのポインタを作成できる言語ならば，内部状態の表現に関係なくどの言語ででも COM オブジェクトを使える

図に，COM オブジェクトに実装されている，MyInterface という仮定のインターフェースの仮想テーブルのレイアウトを示します。

インターフェース仮想テーブル1111011

COM オブジェクトを外部（別のモジュール）からインスタンス化するには，CoClass にクラスファクトリとクラス識別子（CLSID: class identifier）がなければなりません。クラスファクトリについての詳細は，「クラスファクトリ」を参照してください。CoClass のこれらのユニークな識別子を使うと，新しいインターフェースがそのクラスに実装されるたびに，透過的に CoClass を更新できます。インターフェースには名前ではなくユニークな識別子を使ってもアクセスできるので，CoClass はインターフェースの新旧のバージョンともに（メソッドと実装の集合として）サポートできます。新しいインターフェースはバージョン間の衝突（DLL を使うときによく起こる問題）を生じないでメソッドを変更または追加できます。さらに，インターフェースポインタには多様性があるので，どの種類のインターフェースポインタも種類に関係なく COM オブジェクトを操作できます。COM を使うと，作成したベンダーも時期も異なるオブジェクト間でも衝突せずに対話できます。


COM and ActiveX servers
COM and ActiveX servers1111012

Section topics 	参照

COM サーバーは，クライアントのアプリケーションまたはライブラリにサービスを提供するアプリケーションまたはライブラリです。COM サーバーがインプロセスサーバーの場合は，クライアントと同じプロセス空間で DLL を実行しています。ローカルサーバーの場合は，クライアントと同じマシンの別のプロセス空間で EXE を実行しています。リモートサーバーの場合は，クライアントとは別のマシンでアプリケーションを実行しています。COM サーバーは COM オブジェクトが存在するモジュールです。OLE オートメーションオブジェクト，ActiveX コントロール，ActiveForm のコードを持つ COM サーバーは ActiveX サーバーです。Delphi には，ActiveX サーバーの基本機能をカプセル化するクラスがあります。基本機能には以下のものがあります。

サーバーの登録，クラスの登録，サーバーのロードとアンロード，オブジェクトのインスタンス化に必要なルーチンのエクスポート

サーバー上に実装するオブジェクト用クラスファクトリの作成と管理

サーバーに関する基本情報（サーバーの種類，ヘルプファイル，サーバー名，タイプライブラリなど）の提供

Delphi サーバークラスにはタイプライブラリが必要です。サーバーで使えるオブジェクトとインターフェースについての情報は，各モジュールのタイプライブラリに入っています。タイプライブラリの概要については，「タイプライブラリ」を参照してください。タイプライブラリの作成についての詳細は，「タイプライブラリの操作」を参照してください。OLE オートメーションサーバーの作成については，「OLE オートメーションサーバーの作成」を参照してください。


Class factories
Class factories1111013

Section topics 	参照

クラスファクトリは，COM オブジェクトを作成し登録する特殊な種類のオブジェクトです。クラスファクトリは CoClass をインスタンス化する標準的な方法です。CLSID とクラスファクトリがないクラスは，コンストラクタを呼び出してインスタンス化しなければなりません。クラスファクトリを使ってオブジェクトをインスタンス化すれば，クライアントは CoClass のユニークな識別子だけ知っていればよく，それ以外の情報は不要です。クラスファクトリはコンストラクタメソッドのすべての特性や引数などを処理します。

通常は，CoClass の定義ごとにクラスファクトリがあります。クラスファクトリクラスは複数の CoClass に関連付けることができ，それぞれの CoClass をこのクラスがインスタンス化できます。ただし，クラスファクトリ自体をインスタンス化すると，コンストラクタに渡される特定のクラス識別子（CLSID）に関連付けられます。このパラメータは，そのクラスファクトリオブジェクトがインスタンス化できる CoClass を示します。このため，クラスファクトリクラスは複数の CoClass に使えますが，クラスファクトリの各インスタンスは 1 つの  CoClass のインスタンスの作成にしか使えません。

Instantiating CoClasses1111014

CoClass は Windows API グローバル関数 CoGetClassObject を呼び出してインスタンス化できます。CoGetClassObject はレジストリ内で CLSID を調べ，サーバー用のパスを探し，サーバーをロードし，クラスファクトリインターフェース（通常は IClassFactory）へのポインタを提供します。IClassFactory ポインタはクラスファクトリの CreateInstance メソッドを呼び出し，このメソッドが CoClass のインスタンスを作成します。

かわりに Windows API グローバル関数 CoCreateInstance を呼び出してこれらの操作をさせることもできます。サーバーをロードした後，CoCreateInstance が自動的に CoGetClassObject 関数を呼び出し，さらに IClassFactory ポインタを通じて CreateInstance メソッドを呼び出します。ただし，1 つのクラスの複数のインスタンスを作成する場合は，その CLSID に対してクラスファクトリを 1 つだけ作成し，クラスファクトリの CreateInstance メソッドを直接呼び出す方が速く処理できます。CoGetClassObject だけが，クラスファクトリの特定のインスタンスを複数回直接使えるように IClassFactory インターフェースポインタを提供できます。したがって，処理効率が重要な場合に特定の CoClass の複数のインスタンスを作成するときは，CoGetClassObject を呼び出し，インスタンス化ごとにレジストリを確認してサーバーをロードするオーバーヘッドを節約した方が速く処理できます。

Delphi class factory classes1111015

クラスファクトリにするオブジェクトは，IClassFactory インターフェースをサポートしなければなりません。Delphi CoClass には対応するクラスファクトリクラスがあります。これらのクラスは IClassFactory インターフェースを実装します。また，ライセンス付与が必要な ActiveX オブジェクトの場合は IClassFactory2 インターフェースを実装します。Delphi クラスファクトリオブジェクトは，サーバーがあるユニットの初期化セクションで作成されるので，サーバーがロードされるとクラスファクトリは自動的に使えるようになります。COM サーバーまたは ActiveX サーバー用に使う Delphi COM サーバークラスには，クラスファクトリを管理するメソッドがあります。クラスファクトリの参照カウントが記録されるので，サーバーはいつ自分をアンロードできるかわかります。


Type libraries
Type libraries1111016

Section topics 	参照

タイプライブラリは，ActiveX サーバーで使えるオブジェクトとインターフェースの型を識別するのに使います。タイプライブラリは，COM サーバーまたは ActiveX サーバーの型情報が入っているファイルです。これは，アプリケーション，DLL または Windows EXE に関する必要な情報がユニット，ヘッダーファイル，DEF ファイル，インポートライブラリに入っているのと似ています。実際には，これらのファイルに格納していたシンボル情報のほとんどは，タイプライブラリ 1 つに格納できます。この情報は，オブジェクトの実行中インスタンスに問い合わせるか，タイプライブラリをロードして読み出せば入手できます。

この節では，タイプライブラリについて，何が入っているか，どのように作成していつ使うか，どのようにアクセスするかを説明します。異なる言語間でインターフェースを共有する場合のために，この節の最後にタイプライブラリツールの使い方についてのヒントを示します。

The contents of type libraries1111017

タイプライブラリには，どのインターフェースがどの COM オブジェクトにあるか，それにインターフェースメソッドへの引数の型と数などを示す typeinfo が入っています。これらの記述には CoClass のユニークな識別子（CLSID）やインターフェースのユニークな識別子（IID）が含まれているので，CoClass やインターフェースに正しくアクセスできます。また，これらの記述には OLE オートメーションインターフェースメソッドのディスパッチ識別子（dispID）も含まれています。このほかにタイプライブラリには以下のものが入っています。

カスタムインターフェースに関連付けられたカスタム型情報

ActiveX サーバーがエクスポートするがインターフェースメソッドではないルーチン

列挙型のデータ型に関する情報

ほかのタイプライブラリからの型記述への参照

ディスパッチインターフェースと一緒にタイプライブラリを使う方法についての詳細は，「OLE オートメーションインターフェース」を参照してください。

Creating type libraries1111018

従来の開発ツールを使ってタイプライブラリを作成するには，インターフェース記述言語（IDL: Interface Description Language）またはオブジェクト記述言語（ODL: Object Description Language）でスクリプトを作成し，コンパイラを経由してそのスクリプトを実行します。ただし，Delphi にはタイプライブラリエディタが用意されているので，IDL や ODL を習得して使わなくてもタイプライブラリを作成できます。タイプライブラリエディタは標準のタイプライブラリと Delphi インターフェースファイル（.PAS ファイル）を自動的に生成します。タイプライブラリはデフォルトではリソースとして生成されます。Delphi インターフェースファイルには Object Pascal 構文を使ったインターフェース定義が入っています。タイプライブラリエディタを使ってインターフェースや CoClass を作成する方法についての詳細は，「タイプライブラリの操作」を参照してください。

When to use type libraries1111019

外部ユーザーにエクスポーズする一連のオブジェクトごとにタイプライブラリを作成することが重要です。タイプライブラリが役立つか必要な状況は以下のとおりです。

仮想テーブルのバインディングをサポートする，エクスポーズされたオブジェクトは，コンパイル時に仮想テーブル参照がバインドされるので，タイプライブラリで記述しなければならない。仮想テーブルとコンパイル時のバインディングについての詳細は，「OLE オートメーションインターフェース」を参照

IProvideClassInfo インターフェースをサポートするクラスからインスタンス化されたオブジェクト（Delphi TTypedComObject クラスのすべての下位オブジェクトなど）にはタイプライブラリが必要である

ActiveX コントロールにはタイプライブラリが必要である。この場合，ActiveX コントロールが入っている DLL または OCX にリソースとしてタイプライブラリが入っていなければならない

OLE オートメーションサーバーを実装するアプリケーションの場合，クライアントがアーリーバインディングできるようにタイプライブラリを用意しなければならない

ドラッグアンドドロップで使うオブジェクトを特定する場合，タイプライブラリは必須ではないが，あると役立つ

各種オブジェクトのタイプライブラリ要件については，表「OLE／ActiveX オブジェクト要件」を参照してください。タイプライブラリを必要とするコンパイル時のバインディングまたはアーリーバインディングについての詳細は，「OLE オートメーションインターフェース」を参照してください。

内部（アプリケーション内）だけで使うインターフェースを定義する場合，タイプライブラリを作成する必要はありません。インターフェース定義は Object Pascal ユニットを使って直接作成できます。Delphi でインターフェースを宣言するときの構文については，『Object Pascal 言語ガイド』を参照してください。

Accessing type libraries1111020

バイナリタイプライブラリは通常はリソースファイル（.RES）の一部か，ファイル名拡張子が .TLB のスタンドアロンファイルの一部です。タイプライブラリをいったん作成すると，オブジェクトブラウザやコンパイラなどのツールは特殊な型インターフェース ITypeLib，ITypeInfo，ITypeComp を経由してタイプライブラリにアクセスできます。ITypeLib インターフェースはタイプライブラリ内の型情報にアクセスできるようにします。各オブジェクトの記述にアクセスするには，ITypeInfo インターフェースを使います。Delphi はタイプライブラリをほかのアプリケーションからインポートして使えます。OLE アプリケーションや ActiveX アプリケーション用に使うほとんどの Delphi クラスは，タイプライブラリやオブジェクトの実行中インスタンスで型情報の格納や取り出しを行うのに不可欠のインターフェースをサポートします。Delphi クラス TTypedComObject は，型情報を提供するインターフェースをサポートし，Delphi ActiveX オブジェクトフレームワークの土台の役目をします。

Benefits of using type libraries1111021

タイプライブラリはアプリケーションに必須ではありませんが，タイプライブラリを使うと以下の利点があります。

コンパイル時に型チェックができる

OLE オートメーションに対してアーリーバインディングを使え（バリアントを通じて呼び出す場合とは対照的），仮想テーブルもデュアルインターフェースもサポートしないコントローラはコンパイル時に dispID を符号化できるので実行時の処理効率が上がる

型ブラウザがライブラリをスキャンできるので，開発者のオブジェクトの特徴をクライアントが調べることができる

RegisterTypeLib 関数を使って，エクスポーズしたオブジェクトをシステムレジストリに登録できる

UnRegisterTypeLib 関数を使って，アプリケーションのタイプライブラリをシステムレジストリから完全に解除できる

OLE オートメーションはタイプライブラリの情報を使って，ほかのプロセスでオブジェクトに渡されたパラメータをパッケージ化するので，ローカル／リモートサーバーがアクセスしやすくなる

Using type library tools for sharing interfaces with C++1111022

異なる言語間でインターフェースを共有するためにヘッダーファイルが必要なタスクの場合，Delphi タイプライブラリエディタツールと標準のタイプライブラリコマンドラインツールの両方を使ってコードを生成できます。タイプライブラリを操作するツールには，以下のものがあります。

Microsoft IDL コンパイラ（MIDL）は IDL スクリプトをコンパイルしてタイプライブラリを作成する。MIDL にはヘッダーファイルを生成するためのオプションスイッチがある

MKTYPLIB は，ODL スクリプトをコンパイルしてタイプライブラリを作成する ODL コンパイラである

Delphi TLIBIMP（タイプライブラリインポート）ツールは既存のタイプライブラリを取り出して Delphi インターフェースファイルを作成する。このツールは Delphi タイプライブラリエディタに組み込まれている

OLEView はタイプライブラリブラウザツールであり，Microsoft の Web サイトにある

Object Pascal と C または C++ の間でインターフェースを共有するため，ヘッダーファイルを用意したいことがあります。C または C++ 用に IDL ファイルを作成し，ヘッダーファイルスイッチとタイプライブラリスイッチの両方をオンにして IDL ファイルをコンパイルできます。ただし，Delphi を使って Object Pascal でアプリケーションを作成する場合，インターフェースが入っているヘッダーファイルを次の手順で簡単に生成できます。

1.	Delphi タイプライブラリエディタを使って，Object Pascal でタイプライブラリファイルを作成します。

2.	タイプライブラリを取り出し，OLEView で開きます。

3.	右側に表示される IDL スクリプトをコピーして .IDL ファイルに貼り付けます。

4.	MIDL で .IDL ファイルをコンパイルして C ヘッダーファイルを作成します。

ヘッダーファイルにはインターフェースに関する情報が入ります。C アプリケーションと C++ アプリケーションはこの情報を利用できます。


Using interfaces in Delphi
Using interfaces in Delphi1111023

Section topics 	参照

インターフェースをいつどのように使うかは，提供したいサービスの種類や，アプリケーションを実行する必要があるプロセス空間によって決まります。特定の型のオブジェクトにサービスを提供し，そのサービスを利用するための規則を規定している定義済みインターフェースを COM ライブラリの拡張機能で入手できます。以降の各節では，インターフェースを選択，作成，実装する方法と，これらのインターフェースを Delphi アプリケーションで使う利点について説明します。


Using interfaces as services
Using interfaces as services1111024

Section topics 	参照

インターフェースは，オブジェクトのサービス（状態の保存，ビジュアル編集，ドラッグアンドドロップなど）にアプリケーションがアクセスする手段です。作成するオブジェクトの型とその型で実装が必要または可能なインターフェースは，利用するサービスによって，またクライアントかサーバーのどちらを作成するかによって異なります。どの方法を使うか判断するための基準は以下のとおりです。

Predefined services1111025

定義済みサービスの場合，開発者がクライアントアプリケーションまたはサーバーアプリケーションを作成します。つまり，サービスにアクセスして使うか，またはクライアントにサービスを提供します。アプリケーションはクライアントにでもサーバーにでもできます。特定の定義済みサービス用にクライアントアプリケーションを作成する場合は，そのサービスを提供するオブジェクトの型や，そのオブジェクトにアクセスする方法がわかっていなければなりません。サービスを使うオブジェクトのインスタンスを作成する方法を理解し，適切なインターフェースを実装しなければなりません。サーバーの場合は，サービスを提供するオブジェクトを作成する方法を理解し，そのサービスを提供するための適切なインターフェースを実装しなければなりません。

特定の型（COM，OLE，ActiveX など）のすべてのアプリケーションに対して標準的なサービスは，これらのライブラリが提供するインターフェースで定義されています。たとえば，OLE アプリケーションの場合，インターフェースが提供するサービスは以下の 4 つの分野に分かれています。

オブジェクト間の通信

基礎構造のサポート

基本的なリンクと埋め込み

高度な機能

OLE の基本機能を持つオブジェクトを作成する場合は，最初の 2 つの分野のインターフェースをいくつか実装するだけですみます。OLE ドキュメントや ActiveX コントロールの場合は，残りの分野のインターフェースも実装します。作成するオブジェクトの型ごとの規則については，それぞれの OLE ライブラリまたは ActiveX ライブラリを参照してください。

Custom services1111026

カスタムサービスを作成する場合は，特定のサービスのソフトウェアアーキテクチャの基本設定を定義して，オブジェクトをそのコンテキスト内で作成し実装できるようにしなければなりません。定義済みサービスの場合と同様に，クライアントとサーバーは，特定の型のオブジェクトの作成，アクセス，操作の規則に従っていなければなりません。


Using interface libraries
Using interface libraries1111027

Section topics 	参照

特定の型のオブジェクトを作成し，使う場合は，その型の標準オブジェクトに対応するライブラリと規則を参照してください。利用できるインターフェースライブラリと拡張機能の種類は以下のとおりです。

COM interfaces1111028

COM はインターフェースの標準ライブラリを定義します。たとえば，インターフェースの基本機能を確立する IUnknown インターフェースや，COM オブジェクトを外的にインスタンス化するためクラスファクトリオブジェクトで必要な IClassFactory インターフェースがあります。COM インターフェースを実装するクラスを作成したい場合は，Delphi COM フレームワークが提供する TInterfacedObject，TComObject，TTypedComObject，TComObjectFactory，TTypedComObjectFactory の各クラスを参照する必要があります。

OLE/ActiveX extensions1111029

OLE ライブラリの COM 拡張機能には多数のオブジェクト型が含まれており，それぞれサポートが可能なまたは必要なインターフェースを定義しています。OLE 自体も多数の汎用インターフェース（通常「IOle」で始まるもの）を提供します。

OLE と同様に，ActiveX は COM を実装したものです。ActiveX 技術を使う代表的なアプリケーションは ActiveX ドキュメントと ActiveX コントロールです。ActiveX は OLE より新しい技術であり，COM の拡張機能として開発され，サイズや処理速度が最適化されています。ただし，OLE が徐々に発展してきたときに ActiveX が出現したので，これら 2 つの技術は部分的に重複し始めましたが，現在はその違いが明確になりつつあります。

図に，OLE 拡張機能と ActiveX 拡張機能の関係，およびこれらの拡張機能が COM をベースにどのように構築されているかを示します。

OLE／ActiveX 技術の図

OLE Documents1111030

OLE ドキュメントはドキュメントオブジェクトとコンテナ用のインターフェースのライブラリです。このライブラリは自身のインターフェースを使って各種のサービス（コンテナアプリケーションとオブジェクトアプリケーションの間でリンクと埋め込みのために行う通信など）を提供します。OLE ドキュメントコンテナを作成するには，TOleContainer クラスを使います。

OLE Automation1111031

OLE オートメーションの場合， IDispatch インターフェースを実装し，ディスパッチインターフェース型をサポートしなければなりません。OLE オートメーションには，パラメータをパッケージ化しプロセス空間の間で送信したり，オブジェクトにストレージを提供したり，オブジェクト名を変換するためにインターフェースが提供するサービスがあります。OLE オートメーションが必要な場合は，TAutoObject を使って IDispatch インターフェースを実装します。

ActiveX controls1111032

ActiveX コントロール（OLE コントロールまたは OCX ともいいます）は，ActiveX ライブラリにインターフェースを実装するオブジェクトです。これらのインターフェースは，イベントの送出，データソースへのバインド，ライセンス付与のサポートの機能をオブジェクトに提供します。Delphi の TActiveXControl クラスと TActiveForm クラスやウィザードを使えば，ActiveX オブジェクトは簡単に作成できます。

Implementing custom/third party interfaces1111033

カスタムインターフェースはオブジェクトベースのアプリケーションを開発するときに作成できます。サードパーティの標準化グループが標準拡張機能を定義しているサービスの場合，COM，OLE，ActiveX の各ライブラリの標準拡張機能と同様にその標準の拡張機能を使えます。自分でライブラリと規則を定義することもできます。カスタムインターフェースまたはサードパーティインターフェースを実装するオブジェクトを作成する場合は，TComObject，TTypedComObject，TAutoObject のいずれかを基本クラスとして使うとよいでしょう。


Creating and accessing interfaces
Creating and accessing interfaces1111034

Section topics 	参照

COM ライブラリ，OLE ライブラリ，サードパーティのライブラリのいずれかを経由して利用できる定義済みのインターフェースを使うことも，独自にインターフェースを作成することもできます。独自にインターフェースを作成するには，インターフェース定義を作成してから，インターフェースを実装するクラスを作成します。Delphi でインターフェースをサポートするクラスを宣言するときの構文については，『Object Pascal 言語ガイド』を参照してください。このマニュアルには Delphi でインターフェースを作成して使う手順も詳細に記述されています。この手順をまとめると以下のようになります。

インターフェースの宣言

インターフェースをサポートするクラス定義の作成

クラスでのインターフェースメソッドの実装

インターフェース参照の作成

インターフェース参照を経由したインターフェースメソッドの呼び出し

オブジェクトでのインターフェースの問い合わせ

VCL コントロールのラッパーである ActiveX コントロールを作成すると，Delphi のウィザードが以上の手順のほとんどを自動的に処理します。ウィザードを利用すると，ActiveForm オブジェクトや OLE オートメーションオブジェクトも簡単に作成できます。

メモ	CoClass は一連のインターフェースの実装だけで構成されるクラスですが，インターフェースを実装する Delphi クラスには，インターフェースで宣言されるメソッドしか入れられないわけではありません。Delphi クラスにはそれ以外のデータやメソッドを入れることができます。ただし，追加のデータやメソッドには，CoClass としてインスタンス化されたオブジェクトへのインターフェース参照を使ってアクセスすることはできません。


Creating classes that support interfaces
Creating classes that support interfaces1111035

Section topics 	参照

Delphi では，アプリケーション内部用の COM 互換インターフェースを実装するときに基本クラスとして使える単純なクラス TInterfacedObject が定義されています。TInterfacedObject は技術的には CoClass ではありません。COM は，クラス識別子（CLSID）が登録されていなければならず，クラスファクトリを使って外的にインスタンス化できなければならないからです。このため TInterfacedObject は，1 つのモジュール内またはインプロセスクライアント（アプリケーションの外にあるが同じプロセス空間にあります）で内的にインスタンス化されるオブジェクトを作成するときの基本クラスとして使います。

TInterfacedObject は IUnknown のメソッドを実装するので，インターフェース付きオブジェクトを作成するときに便利な基本クラスの役割を果たします。次に System ユニット内での TInterfacedObject クラスの宣言を示します。

type

  TInterfacedObject = class(TObject, IUnknown)

  private

    FRefCount: Integer;

protected

    function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;

    function _AddRef: Integer; stdcall;

    function _Release: Integer; stdcall;

  public

    property RefCount: Integer read FRefCount;

  end;

TInterfacedObject からの直接の派生は簡単にできます。次に，例として TInterfacedObject の直下の派生オブジェクトである TDerived が IPaint インターフェースを実装する宣言の例を示します。

type

  TDerived = class(TInterfacedObject, IPaint)

    ...

  end;


Using classes that support interfaces
Using classes that support interfaces1111036

Section topics 	参照

TInterfacedObject も含めて，インターフェースを実装するすべてのクラスでは，動的バインディングを使うことによってインターフェースに真の多様性を提供できます。たとえば，次の手続きがあるとします。

var

  X: IPaint;

  P: TInterfacedObject;

begin

  P := TInterfacedObject.Create;

  X := P;

動的バインディングの機能により，TInterfacedObject 型の引数 P を IPaint インターフェース変数 X に代入することができます。コンパイラは，as 演算子に対して P の持つ IUnknown インターフェースの QueryInterface メソッドを呼び出すコードを生成します。これは，P の型からは P のインスタンスが実際に IPaint インターフェースをサポートしているかどうか，コンパイルの時点では判断できないためです。TInterfacedObject クラスで実装している QueryInterface を呼び出すことにより，実行時に P が IPaint インターフェースを持っているかどうかを判断できます。これにより，確実に X の IPaint インターフェースに代入することができます。

インターフェースを持たない VCL クラスを，インターフェースを実装するクラスの基本クラスとして使うと，このような代入でコンパイルエラーが発生します。次に例を示します。

var

  X: IPaint;

  P: TObject;

begin

  P := TObject.Create;

  X := P;	// 互換性のない型

P の型が IUnknown と IPaint のどちらも実装していないため，コンパイルエラーが発生します。QueryInterface メソッドが基本クラスで使えない場合は，コンパイル時に IPaint インターフェースを静的に解決しなければなりません。このようなインターフェースの代入規則についての詳細は，『Object Pascal 言語ガイド』を参照してください。

IUnknown を実装するクラスを基本クラスとして使うもう 1 つの利点は，QueryInterface のバージョン管理機能が利用できることです。ソフトウェアモジュールが更新された場合，実行時に QueryInterface を呼び出して，このメソッドを実装したオブジェクトの現在の機能について問い合わせることができます。オブジェクトの古いインターフェースのどの新バージョンでも，どんな新しいインターフェースまたは機能でも，新しいクライアントはすぐに利用できるようになります。オブジェクトは既存のクライアントコードと完全な互換性を保っているため，クライアントを再コンパイルする必要はありません。さらに，インターフェースの実装は完全に隠れていますがメソッドやパラメータは一定なので，開発者はそのインターフェースに依存しているクライアントのコードに影響を与えずに，処理効率を上げるなどの内部的な理由により実装を変更できます。


Interfaces and code reuse
Interfaces and code reuse1111037

Section topics 	参照

いくつものオブジェクトで広範囲に一連の操作（ストリーミングなど）を行う場合にはインターフェースが役立ちます。IStream などのインターフェースやデータベース対応インターフェースを使うと，オブジェクトがコードを再使用でき，各種のアプリケーションに一貫して同じコードを適用できます。これらの種類のインターフェースは多数の Windows コントロールオブジェクト間で使えます。つまり，Delphi や C++ などの各種の言語で作成されたオブジェクト間で共有でき，これらのオブジェクトのユーザーに影響を及ぼさずに更新できます。

Sharing interfaces between classes1111038

次の例に，インターフェースを使ってクラスの使い方と実装方法を分ける方法を示します。2 つのクラスは，同じ基本クラスから派生していなくても同じインターフェースを持つことができます。直接関係のないオブジェクト同士でも，同じインターフェースを実装している限り，多様性のある呼び出しが可能です。たとえば，次のインターフェースがあるとします。

IPaint = interface

  procedure Paint;

end;

また，次に示すようにクラスが 2 つあるとします。

TSquare = class(TInterfacedObject, IPaint)

  procedure Paint;

end;

TCircle = class(TInterfacedObject, IPaint)

  procedure Paint;

end;

ここで 2 つのクラスは互いに代入互換性を持ちませんが，次の例に示すようにどちらも IPaint の変数と代入の互換性を保っています。

var

  Painter: IPaint;

begin

  Painter := TSquare.Create;

  Painter.Paint;

  Painter := TCircle.Create;

  Painter.Paint;

end;

従来の Object Pascal のプログラミングであれば，たとえば仮想メソッド Paint を実装した TFigure を定義し，TCircle と TSquare を TFigure から派生させ，そこでそれぞれのクラスで Paint メソッドをオーバーライドすることで実装を行うことになるでしょう。上の例の IPaint は，このような TFigure に置き換わるものです。今度は次のインターフェースを考えてみましょう。

IRotate = class

  procedure Rotate(Degrees: Integer);

end;

このインターフェースは，四角形の描画には有効ですが，正円に対しては意味を持ちません。このインターフェースを追加すると各クラスは次のようになるでしょう。

TSquare = class(TInterfacedObject, IPaint, IRotate)

  procedure Paint;

  procedure Rotate(Degrees: Integer);

end;

TCircle = class(TInterfacedObject, IPaint)

  procedure Paint;

end;

さらに指定されたパターンで塗りつぶした円を描画する TFilledCircle を作成し，それに IRotate インターフェースを持たせて，塗りつぶしのパターンの角度を変更させることもできるでしょう。

Using interfaces with procedures1111039

インターフェースを使うと，オブジェクトを特定の基本クラスから派生させずに，包括的にオブジェクトを処理できる手続きを作成することもできます。たとえば，前述の IPaint インターフェースと IRotate インターフェースを使い，次の手続きを作成できます。

procedure PaintObjects(Painters: array of IPaint);

var

  I: Integer;

begin

  for I := Low(Painters) to High(Painters) do

    Painters[I].Paint;

end;

procedure RotateObjects(Degrees: Integer; Rotaters: array of IRotate);

var

  I: Integer;

begin

  for I := Low(Rotaters) to High(Rotaters) do

    Rotaters[I].Rotate(Degrees);

end;

RotateObjects にとってはオブジェクトを塗りつぶす方法をオブジェクト自体が知っている必要はなく，PaintObjects にとってはオブジェクトを回転させる方法をオブジェクト自体が知っている必要はありません。こうすることにより，これらのオブジェクトは TFigure クラスだけで機能するように作成したときよりも用途が広がります。

Using interfaces with generic algorithms1111040

インターフェースを使うと，ソートなどの一般的なアルゴリズムも実装できます。次に，ICompare インターフェースの例と，ICompare インターフェースを使って TObject の配列をソートする QuickSort 手続きの例を示します。

ICompare = interface

  function CompareWith(Object: TObject): Integer;

end;

...

procedure QuickSort(Objects: array of TObject);

  procedure Sort(Objects: array of TObject; Left, Right: Integer);

  var

    I, J: Integer;

    Object, Temp: TObject;

    Compare: ICompare;

  begin

    repeat

    I := Left;

    J := Right;

    Object := Objects[(Left + Right) div 2];

    Compare := Object as ICompare;

    repeat

      while Compare.CompareWith(Objects[I]) < 0 do Inc(I);

      while Compare.CompareWith(Objects[J]) > 0 do Inc(J);

      if I <= J then

      begin

        Temp := Objects[I];

        Objects[I] := Objects[J];

        Objects[J] := Temp;

        Inc(I);

        Inc(J);

      end;

          until I > J;

    if Left < J then Sort(Objects, Left, J);

    Left := I;

    until I >= Right;

  end;

begin

  Sort(Objects, Low(Objects), High(Objects));

end;

以上のルーチンは，インターフェースを使わないでも実装できますが，その場合は，CompareWith メソッドを実装する共通の上位クラスをすべてのオブジェクトが共有していなければなりません。しかし，これがいつもできるとは限りません。ソートするすべてのクラスの上位クラスを変更したくない場合も，この上位クラスへのアクセス権を持っていない場合もあります。インターフェースを使えば，上位クラスを変更しないでも，サポートしたいクラスの下位クラスとして，ICompare を実装するクラスを作成できます。


OLE and ActiveX objects
OLE and ActiveX objects1111041

Section topics 	参照

OLE 拡張機能と ActiveX 拡張機能は COM 仕様に従っています。この仕様では，オブジェクトは CoClass からインスタンス化しなければなりません。CoClass にはユニークな識別子（CLSID）とクラスファクトリが必要です。

OLE オブジェクトや ActiveX オブジェクトを使うと利点があると同時に制約も生じます。これらのオブジェクトはビジュアルの場合も非ビジュアルの場合もあり，クライアントと同じプロセス空間でも別のプロセス空間でも実行できます。ただし，クロスプロセスまたはリモート手続きを呼び出すときは，パラメータのパッケージ化とパッケージ解除が必要です。インターフェースメソッドのパラメータをパッケージ化し，クライアントアプリケーションとサーバーアプリケーションを区切るプロセス境界を超えて送信するプロセスをマーシャリングといいます。リモートアプリケーションやクロスプロセスアプリケーションを処理する場合，パラメータの種類によってマーシャリングの方法が異なり，OLE オブジェクトや ActiveX オブジェクトの型によってマーシャリングプロセスの処理方法が異なることに注意してください。

表 36.1 に，作成可能な OLE オブジェクトの型，ビジュアルか非ビジュアルかの区別，実行できるプロセス空間，マーシャリングの処理方法，タイプライブラリの必要性の有無を示します。

OLE/ActiveX object requirements:1111042

OLE オブジェクト	ビジュアル	プロセス空間	通信プロセス	タイプライブラリの使用
OLE／ActiveX  ドキュメント	通常は ビジュアル	インプロセスまたはクロスプロセス	マーシャリング用バーブ	不要
OLE オートメーション	場合による	インプロセス，クロスプロセス，リモートプロセスのいずれか	IDispatch 自動 マーシャリング	望ましい
ActiveX コントロール	通常は ビジュアル	インプロセス	IDispatch 自動 マーシャリング	必要
カスタムインターフェース オブジェクト	選択可能	インプロセス，クロスプロセス，リモートプロセスのいずれか	手動マーシャリング	望ましい


OLE/Active Documents
OLE/Active Documents1111043

Section topics 	参照

通信，リンク，埋め込み用の各インターフェースによって OLE が提供する 1 つのサービスセットが OLE ドキュメントです。これらのオブジェクトには，OLE 機能（リンクと埋め込み，ドラッグアンドドロップ，ビジュアル編集，インプレースアクティベーション）があります。OLE ドキュメントを操作するには，標準的な動作（ドラッグアンドドロップやビジュアル編集など）をこのドキュメント用に提供するインターフェースを必要なだけ実装します。これらのインターフェースを実装すると，OLE ドキュメントは形式が異なるデータつまりオブジェクト（サウンドクリップ，スプレッドシート，テキスト，ビットマップなど）をシームレスに統合できます。

ActiveX コントロールと異なり，OLE ドキュメントはインプロセスサーバーに限定されずクロスプロセスアプリケーションでも使えます。また，OLE オートメーションオブジェクトがビジュアルな場合はほとんどありませんが，OLE ドキュメントオブジェクトはほかのアプリケーションでビジュアルに操作できます。ビジュアルに操作できるようにするため，OLE ドキュメントオブジェクトは 2 種類のデータつまりプレゼンテーションデータ（ディスプレイまたは出力デバイスでのオブジェクトのビジュアル表示用）とネイティブデータ（オブジェクトの編集用）に関連付けられています。

OLE ドキュメントオブジェクトは，ドキュメントコンテナの場合もドキュメントサーバーの場合もあります。Delphi には OLE ドキュメントコンテナの基本クラスとして使えるクラス TOleContainer があります。OLE ドキュメントサーバー用のオブジェクトを作成するには，1 つの Delphi COM 基本クラスを使い，オブジェクトがサポートする必要のあるサービスに基づいてそのオブジェクト型に適切なインターフェースを実装します。OLE ドキュメントサーバーの作成と使い方についての詳細は，Microsoft Web サイトを参照してください。

メモ	OLE ドキュメント用の OLE 仕様には，クロスプロセスアプリケーション用のマーシャリングのサポートが組み込まれていますが，OLE ドキュメントがどの型（ウィンドウハンドル，メニューハンドルなど）を使うかは特定のマシン上のシステムに固有なので，OLE ドキュメントはリモートサーバー上では実行されません。


OLE Automation
OLE Automation1111044

Section topics 	参照

OLE オートメーションとは，あるアプリケーションが別のアプリケーション内のオブジェクトをプログラムを使って制御できる機能のことをいいます。OLE オートメーションオブジェクトのクライアントを OLE オートメーションコントローラと呼び，操作対象のサーバーオブジェクトを OLE オートメーションオブジェクトと呼びます。OLE オートメーションはインプロセスサーバー，ローカルサーバー，リモートサーバーのどこでも使えます。

OLE オートメーションは，2 つの重要な点を特徴としています。

OLE オートメーションオブジェクトは一連のプロパティとコマンドを定義し，型記述によってその機能を記述できなければならない。この条件を満足するには，オブジェクトのインターフェース，インターフェースメソッド，メソッドの引数の情報を提供する手段を用意しなければならない。通常はこの情報はタイプライブラリで入手できる。Delphi では，型情報の問い合わせに対して，オートメーションサーバーがただちに型情報を生成することもできる

OLE オートメーションオブジェクトはほかのアプリケーションがこれらのメソッドにアクセスして使えるようにしなければならない。これには IDispatch インターフェースを実装しなければならない。このインターフェースを経由すれば，オブジェクトはそのすべてのメソッドとプロパティをエクスポーズできる。型情報によってオブジェクトのメソッドがわかったら，このインターフェースの一次メソッドを使ってそのメソッドを呼び出せる

どのプロセス空間でも実行できる非ビジュアル OLE オブジェクトを作成して使いたい場合，開発者は OLE オートメーションを使えます。この理由の 1 つは，OLE オートメーションが IDispatch インターフェースを実装してクロスプロセスアプリケーション間の通信を自動的に行えるようにする点にあります。IDispatch インターフェースはマーシャリングプロセスを自動化します。ただし，OLE オートメーションを使うと，利用できる型が制限されます。OLE オートメーション互換型についての詳細は，「OLE と ActiveX の概要」を参照してください。タイプライブラリでこれらの型を使う方法については，「タイプライブラリの操作」を参照してください。

Delphi クラス TAutoObject は IDispatch を実装します。OLE オートメーションオブジェクトを作成する基本クラスとしても使えます。OLE オートメーションに特有の機能は，ActiveX コントロールの土台をなしています。このため，Delphi では TAutoObject が Delphi ActiveX 基本クラスの上位クラスになります。Delphi の OLE オートメーションクラスと ActiveX クラスはデュアルインターフェースもサポートします。ActiveX 階層構造の概要は「Delphi ActiveX Framework」を参照してください。デュアルインターフェースについての詳細は，「デュアルインターフェース」を参照してください。


ActiveX controls
ActiveX controls1111045

Section topics 	参照

ActiveX 技術は COM と OLE を拡張して，ActiveX コントロールに必要な新しい機能をサポートしています。ActiveX コントロールは，インプロセスサーバーで実行するビジュアルコントロールであり，OLE コンテナアプリケーションにプラグインできます。ActiveX コントロールそのものは完全なアプリケーションではありませんが，各種のアプリケーションで再使用可能な作成済み OLE コントロールとみなせます。ActiveX コントロールは OLE オートメーションを使ってそのプロパティ，メソッド，イベントをエクスポーズします。ActiveX コントロールの機能には，イベントを送出し，データソースにバインドし，ライセンス付与をサポートする機能などがあります。Delphi ウィザードを使うと，ActiveX コントロールや ActiveForm を簡単に作成できます。このような型のオブジェクトの作成と使い方についての詳細は，「ActiveX コントロールの作成」と「ActiveForm の作成」を参照してください。

Web サイトでは，Web ページの対話型オブジェクトとして ActiveX コントロールが広く使われるようになってきています。このように，ActiveX は World Wide Web 用の対話型コンテンツを照準とした標準になっており，Web ブラウザを経由して HTML 以外のドキュメントを表示するための ActiveX ドキュメントも使われています。ActiveX 技術についての詳細は，Microsoft Web サイトを参照してください。Web サイトでの Delphi ActiveForm と ActiveX コントロールのアプリケーション化についての詳細は，「ActiveX の Web アプリケーション化」を参照してください。


Visual cross-process objects
Visual cross-process objects1111046

Section topics 	参照

OLE オートメーションオブジェクト，OLE ドキュメント，ActiveX コントロールは一般的に使われるオブジェクトです。これに対し，クロスプロセスアプリケーションでビジュアルに表示して操作できる OLE／ActiveX オブジェクトはそれほど広く使われていません。このような型のオブジェクトを作成するのはもう少し複雑です。これは，クロスプロセスアプリケーションでオブジェクトをビジュアルに操作するときに必要な通信プロトコルが，OLE ドキュメントインターフェースを使うビジュアルオブジェクト用にしか標準化されていないからです。したがって，オブジェクトが実装する 1 つまたは複数のカスタムインターフェースを作成してから，マーシャリングインターフェースを自分で処理しなければなりません。これには，以下の 2 通りの方法があります。

デュアルインターフェース IDispatch を使う。このインターフェースには自動マーシャリングが可能であり，なるべくこの方法が望ましい。もっとも簡単な方法であり，オートメーションオブジェクト（TAutoObject の下位）を作成すると，Delphi がデフォルトでデュアルインターフェースを作成する

マーシャリングクラスを自分で作成する


OLE Automation interfaces
OLE Automation interfaces1111047

Section topics 	参照

OLE オートメーションサーバーは IDispatch インターフェースを実装しているオブジェクトです。IDispatch は IUnknown から派生しているので，このオブジェクトは IUnknown インターフェースも実装します。IUnknown はサーバーオブジェクトがサポートするほかのすべてのインターフェースを管理します。これに対して，IDispatch インターフェースのメソッドは OLE オートメーションオブジェクトのメソッドとプロパティにアクセスできるようにします。図に，IUnknown インターフェースと IDispatch インターフェースをサポートするオブジェクトの IDispatch インターフェースの仮想テーブルを示します。

ディスパッチインターフェースの仮想テーブル

OLE オートメーションコントローラは，OLE IDispatch インターフェースを使って，このインターフェースを実装している OLE サーバーオブジェクトにアクセスするクライアントです。コントローラは最初にオブジェクトを作成してから，オブジェクトの IUnknown インターフェースに IDispatch インターフェースへのポインタについて問い合わせなければなりません。OLE オートメーションコントローラが OLE オートメーションオブジェクトにアクセスするには次の 2 通りの方法があります。

IDispatch インターフェースを使う

デュアルインターフェースが定義されている場合，オブジェクトの仮想関数テーブル（仮想テーブル）のメンバー関数のうちの 1 つを直接呼び出す


Dispatch interfaces
Dispatch interfaces1111048

Section topics 	参照

ディスパッチインターフェースは IDispatch の固有の実装です。プログラマはオブジェクト，メソッド，プロパティの名前を使いますが，IDispatch は内部ではディスパッチ識別子（dispID）を使ってメソッドとプロパティを管理します。この識別子はインターフェースメンバーにユニークな識別値です。OLE オートメーションコントローラがプロパティまたはメソッドを探してアクセスするには，インターフェースメンバーの名前にマップする dispID を事前に入手していなければなりません。これらの dispID は実行時に入手できます。コントローラは IDispatch の GetIDsOfNames メソッドを呼び出して dispID を取得します。コントローラは IDispatch を使ってディスパッチインターフェース用にオブジェクトの型情報を取り出してから，インターフェースメンバー名を特定の dispID にマップできます。コントローラはコンパイル時ではなく実行時にプロパティまたはメソッドにバインドするので，これをレイトバインディングと呼んでいます。

dispID を入手したら，適切なコード（プロパティまたはメソッド）を実行するため IDispatch の Invoke メソッドを呼び出し，プロパティまたはメソッドのパラメータを Invoke パラメータの 1 つにパッケージ化します。Invoke にはコンパイル時の固定の名前が含まれているので，インターフェースメソッドを呼び出すときは引数をいくつでも受け付けることができます。名前付きの引数でもオプションの引数でもかまいません。オートメーションオブジェクトの Invoke の実装はパラメータのパッケージを解除し，プロパティまたはメソッドを呼び出さなければなりません。エラーが発生した場合の処理に備える必要もあります。プロパティまたはメソッドが返されたら，オブジェクトはその戻り値をコントローラに返します。

Advantages and disadvantages when using IDispatch1111049

IDispatch を使う大きな利点は，マーシャリング（異なるプロセス空間で実行中のアプリケーション間の通信プロセス）のサポートが組み込まれていることです。IDispatch を使えば，データ転送のマーシャリングプロセスは自動化されます。つまり，プログラマがさらにプロクシー／スタブを実装する必要はありません。クライアントアプリケーションの場合，パラメータのパッケージを解除しサーバー上でメソッドを呼び出すためにスタブコードを記述する必要はありません。サーバーアプリケーションの場合は，プロセス境界を超えてマーシャリングするためにメソッドのパラメータをパッケージ化するプロクシーコードを記述する必要はありません。

ディスパッチインターフェースを使う欠点は，インターフェースが使えるパラメータの型が基本的な 13 種類の型に制限されることです。これによりユーザーが定義する構造はかなり制限されます。ディスパッチインターフェースがサポートする型についての詳細は，「OLE オートメーションサーバーの作成」を参照してください。

GetIDsOfNames が実行時に名前を dispID にバインドするので，OLE オートメーションオブジェクトではタイプライブラリが不要なことに注意してください。したがって，コンパイル時の型チェックがないため，Invoke が実行時エラーを生じる可能性があります。ただし，Delphi では，ウィザードを使って作成する OLE オートメーションオブジェクトには必ずタイプライブラリが関連付けられているので，この問題が生じることはありません。

ID binding1111050

ディスパッチインターフェースでコンパイル時のバインディングを使えることがあります。タイプライブラリでオブジェクトが記述されている場合，各プロパティまたはメソッドの dispID が固定でオブジェクト型記述に含まれているため，OLE オートメーションコントローラはコンパイル時にタイプライブラリから dispID を読み出すことができます。このようにして dispID を読み出すことを ID バインディングといいます。この場合 GetIDsOfNames が論理的にはコンパイル時に呼び出されるので，ID バインディングは実際には一種のアーリーバインディングです。実行時の IDispatch の呼び出し（つまり Invoke の呼び出し）がレイトバインディングでは 2 回必要ですが，ID バインディングでは 1 回ですむので，通常は処理速度が約 2 倍になります。ID バインディングの利点は，コンパイル時の型チェック機能が向上し，詳細なエラーメッセージを受け取れることです。他方，ID バインディングの欠点は，メソッド名が変更されていないかどうか確認する機能がないことです。GetIDsOfNames が dispID を名前にバインドしたら，Invoke はその名前を番号で参照するだけになるからです。

Dispinterfaces1111051

Delphi では，ディスパッチインターフェースでアーリーバインディングの利点を生かすため，ID バインディングではなく dispinterface を使うことができます。dispinterface の場合，メンバーを dispID にバインドするのに GetIDsOfNames は使いません。特定のインターフェースがあるタイプライブラリをインポートすると，dispID が生成され，dispinterface の対応するメンバーに関連付けられます。dispinterface についての詳細は，『Object Pascal 言語ガイド』を参照してください。次に dispinterface 定義の構文の例を示します。

IButtonXEvents = dispinterface

    ['{8F9C8E22-7FA2-11D0-8080-0020AF74DE39}']

    procedure OnClick; dispid 1;

    procedure OnKeyPress(var Key: Smallint); dispid 2;

end;

dispinterface は ID バインディングの高速処理の利点を備えており，dispID 値ではなくわかりやすいテキスト文字列の名前で呼び出せます。


Dual interfaces
Dual interfaces1111052

Section topics 	参照

OLE オートメーションを使うと，OLE オートメーションコントローラは IDispatch インターフェースではなく仮想テーブルバインディングを使ってメソッドまたはプロパティのアクセサ関数を直接呼び出して，オートメーションオブジェクトにアクセスできます。ただし，コントローラによっては，実行時に IDispatch を経由しないとオブジェクトにアクセスできないことがあります。たとえば，オブジェクトにアクセスして操作する必要があるが，コンパイル時の仮想テーブルレイアウトについて認識していないインタープリタ式のマクロプログラミング言語やスクリプトツールなどがあります。このため，OLE オートメーションでは，ディスパッチインターフェースと仮想テーブルインターフェースを組み合わせた，いわゆるデュアルインターフェースを定義しています。デュアルインターフェースはプロパティとメソッドの両方を IDispatch を経由してエクスポーズするだけでなく，仮想テーブルを経由して直接エクスポーズすることもできます。

Vtable interfaces1111053

仮想テーブルインターフェースはカスタムインターフェースまたはユーザー定義インターフェースであり，このインターフェースを使うと，クライアントは仮想テーブルでの順序と引数の型に基づいてインターフェースメソッドを呼び出せます。仮想テーブルはオブジェクトのメンバーであるすべてのプロパティとメソッドのアドレスを一覧にしたもので，オブジェクトがサポートするインターフェースのメンバー関数も含まれています。仮想テーブルの最初の 3 つのメンバーは IUnknown インターフェースのメンバーです。4 つ目以降のエントリはサポートされているそれ以外のインターフェースのメンバーです。オブジェクトが IDispatch をサポートしない場合，このオブジェクトのカスタムインターフェースのメンバーのエントリが IUnknown のメンバーのすぐ後に続きます。図「インターフェース仮想テーブル」にこの種類の仮想テーブルインターフェースのレイアウトを示します。

クライアントがオブジェクトのタイプライブラリを入手できる場合，IDispatch インターフェースの dispID を取得し，仮想テーブルオフセットに直接バインドできます。このコンパイル時のバインディングにより，オブジェクトの仮想テーブルを経由してそのオブジェクトのどのメソッドやプロパティも直接呼び出すコードが生成されるので，GetIDsOfNames や Invoke を呼び出さないですみます。アクセスは仮想テーブルバインディングを経由して直接行われ，IDispatch 経由での呼び出しはないので，ディスパッチインターフェースの ID バインディングやレイトバインディングよりもこの方法の方が処理速度が上がります。

Defining a dual interface1111054

デュアルインターフェースは IDispatch から派生した COM 仮想テーブルインターフェースです。したがって，デュアルインターフェースのメンバー用に指定するパラメータと戻り型はどれも OLE オートメーション型と互換性が保たれていなければなりません。次にデュアルインターフェースの定義の例を示します。

IProvider = interface(IDispatch)

    ['{6E644935-51F7-11D0-8D41-00A0248E4B9A}']

    function GetData: Variant; safecall;

    function ApplyUpdates(Delta: Variant): Variant; safecall;

    function GetMetaData: Variant; safecall;

    function GetRecords(Count: Integer; var HitEOF: WordBool): Variant; safecall;

    function DataRequest(Input: Variant): Variant; safecall;

    function Reset: WordBool; safecall;

  end;

したがって，デュアルインターフェースはカスタムインターフェースであると同時に，dispinterface でもあります。

デュアルインターフェースの仮想テーブルの最初の 3 つのエントリは IUnknown のメンバーであり，次の 4 つのエントリは IDispatch のメンバーで，残りのエントリはデュアルインターフェースのメンバーに直接アクセスするための COM エントリです。図に，IMyInterface というデュアルインターフェースをサポートするオブジェクト内の IMyInterface インターフェースの仮想テーブルを示します。

デュアルインターフェースの仮想テーブル

Advantages of using dual interfaces1111055

デュアルインターフェースは，以下に示すような，仮想テーブルインターフェースとディスパッチインターフェース両方の利点を備えています。

デュアルインターフェースを使うと，コンパイル型言語で作成したクライアントで，オートメーションオブジェクトメンバーの名前がわかっている場合，仮想テーブルバインディングを行い，仮想テーブル内の関数ポインタに対して直接コンパイルを実行できる

デュアルインターフェースを使うと，カスタムインターフェースの場合と同様に仮想テーブルを経由してインプロセスデュアルオブジェクトを高速で直接呼び出せる。したがって，インプロセスオブジェクトにアクセスする場合，カスタムインターフェースによる効率性が引き続き得られる

コンパイル時に型チェックができるアーリーバインディングを利用できる

型情報を入手できず IDispatch メンバーの呼び出ししかできないオートメーションコントローラでも，デュアルインターフェースを使うとオブジェクトにアクセスできる

デュアルインターフェースには OLE オートメーションの利点もある。すなわち，インターフェースの IDispatch 部分とカスタム部分のどちらにも自動マーシャリングを適用できる。アウトオブプロセスオブジェクトがある場合，自動マーシャリングを利用できる。タイプライブラリの情報に基づいてインターフェースをマーシャリングできるユニバーサルなプロクシー／スタブ実装が提供される

Restrictions when using dual interfaces1111056

インターフェースをデュアルインターフェースとして使うには，そのインターフェースが IDispatch から派生していなければならず，OLE オートメーション互換型を使っていなければなりません。OLE の自動マーシャリングサポートが正しく機能するには，これらの型の制約に従っていなければなりません。これが意味することは以下のとおりです。

デュアルインターフェースにはオートメーションとの互換性を保つための制約がある（別のプロパティオブジェクトを実装する以外にデータ構造を使えない，符号なしの引数を使えない，ワイド文字列を使わなければならないなど）

デュアルインターフェースのすべてのメンバーは関数の戻り値として HRESULT を渡さなければならない

ほかの値を返す必要があるデュアルインターフェースのメンバーは，最後のパラメータを var または out と指定して，関数値を返す出力パラメータであることを示さなければならない

OLE オートメーション互換型についての詳細は，「OLE オートメーションサーバーの作成」を参照してください。タイプライブラリでこれらの型を使う方法については，「タイプライブラリの操作」を参照してください。

メモ	OLE オートメーションの型の制約を受けたくない場合は，IDispatch インターフェースとカスタムインターフェースを別々に実装します。ディスパッチインターフェースに結合されないカスタムインターフェースを定義すれば，すべての引数型を利用できます。これにより，COM クライアントはカスタムインターフェースを使うことができ，OLE オートメーションコントローラは引き続きカスタムインターフェースにアクセスできます。ただし，多少効率は低下します。

Dual interfaces in Delphi1111057

デュアルインターフェースには，IDispatch インターフェースまたは仮想テーブルインターフェースを単独で使うよりもはるかに利点があります。レイトバインディングの IDispatch インターフェースを使う既存の OLE オートメーションコントローラを引き続き使えるからです。利点を考慮するとできるだけデュアルインターフェースを使うのが望ましいため，OLE オートメーションサーバーオブジェクトにはデフォルトでデュアルインターフェースが生成されます。また，Delphi オートメーションコントローラはクライアントアプリケーションとして OLE オートメーションサーバーにアクセスするときに仮想テーブルを利用できます。


Delphi ActiveX Framework
Delphi ActiveX Framework1111058

Section topics 	参照

Delphi ActiveX Framework（DAX）を使うと，VCL コントロールから ActiveX コントロールを構築できます。DAX は OLE オートメーションサーバーの実装のほか，以下に示す各種のコンテナに埋め込める ActiveX コントロールの実装もサポートします。

Internet Explorer 3.0

Delphi 2.0

Borland C++ Builder

Visual C++ 4.x

Visual Basic 4.0 and 5.0

ActiveX Control Pad

DAX のクラスは，COM オブジェクト（ActiveX コントロール，非ビジュアル OLE オートメーションサーバー，ActiveX プロパティページなど）を実装します。ActiveX コントロールの場合，Object Pascal の 2 種類のクラス型（Windows 実装と OLE コントローラオブジェクト）で作業が異なります。開発時には，TWinControl から派生した標準の VCL コントロール（TPanel など）と，TActiveXControl から派生した OLE コントローラオブジェクトを実装します。OLE コントローラオブジェクトは Windows 実装オブジェクトへのポインタを保持しており，実行時のイベントに対応してポインタを作成，操作，廃棄します。Windows 実装オブジェクトはイベントを UI からコントローラオブジェクトに送ります。コントローラオブジェクトはこれらのイベントをそのサイトに送ることもあります。

DAX クラス階層は，以下のオブジェクトから構成されます。

TComObject  TTypedComObject  TAutoObject  TActiveXControl

ActiveX コントロールは TActiveXControl から派生したクラスです。

DAX 階層の各基本クラスは，適切なインターフェースを実装して，特定の型の COM オブジェクトまたは OLE オブジェクトの標準動作を提供します。階層内の各クラスは，COM の拡張時に COM 技術（OLE オートメーションと ActiveX）をミラーリングすることにより，相互に依存させて構築できます。ActiveX コントロール用に継承する機能の概要を以降に示します。これらの各クラスについての詳細は，『ビジュアルコンポーネントライブラリリファレンス』の各エントリを参照してください。Delphi のウィザードでこれらのクラスを使って ActiveX コントロールを簡単に作成する方法についての詳細は，「ActiveX コントロールの作成」を参照してください。


TComObject
TComObject1111059

Section topics 	参照

TComObject は，COM オブジェクトで必要な基本動作とインターフェースを定義する抽象クラスです。TComObject は CLSID とクラスファクトリを持っているので，登録し外的にインスタンス化（別のモジュールからインスタンス化）できます。単純な COM オブジェクトに機能を提供するだけでなく，集約，OLE 例外処理，デュアルインターフェースで使う safecall 呼び出し規約もサポートします。

TComObject は通常はカスタムインターフェースまたは Win95 Shell 拡張機能を実装するときの基本クラスとして使います。タイプライブラリへのアクセスに使う typeinfo インターフェースはサポートしません。


TTypedComObject
TTypedComObject1111060

Section topics 	参照

TTypedComObject は重要な機能つまりタイプライブラリへのアクセス機能（ロードと読み出し）を TComObject に追加します。このため，TTypedComObject とそのすべての下位オブジェクトはタイプライブラリで typeinfo 記述を提供しなければなりません。TTypedComObject は IProvideClassInfo インターフェースをサポートします。このインターフェースにより，クライアントがタイプライブラリを取得しなくても，TTypedComObject のインスタンスが型情報を提供できます。


TAutoObject
TAutoObject1111061

Section topics 	参照

TAutoObject は IDispatch インターフェースを実装することで，OLE オートメーションで必要な基本動作を定義しているクラスです。TAutoObject は，ディスパッチインターフェースをサポートしなければならない OLE オートメーションオブジェクトに使います。ActiveX は OLE オートメーションをベースにしているので，TAutoObject は Delphi ActiveX コントロールクラスの上位クラスです。

TAutoObject は DAX 階層に自動マーシャリング機能を提供します。自動マーシャリング機能が必要なクラスを派生させる場合，TAutoObject を基本クラスとして使えます。クロスプロセスを実行しなければならないオブジェクトを作成する場合，OLE オートメーションの自動マーシャリング機能を使わないときは，開発者が自分でマーシャリング機能を実装する必要があります。自動マーシャリングについての詳細は，「OLE オブジェクトと ActiveX オブジェクト」と，「IDispatch を使う場合の利点と欠点」を参照してください。自分でマーシャリング機能を実装する場合のヒントも記載されています。


TActiveXControl
TActiveXControl1111062

Section topics 	参照

TActiveXControl は Delphi で ActiveX コントロールを作成する抽象クラスです。TActiveXControl は TAutoObject から派生しており，DAX 階層でのその上位クラスのすべての機能を継承しています。生成されるオブジェクトは，OLE オートメーションをサポートし，型情報へのアクセス機能を持つ COM オブジェクトになります。どの ActiveX コントロールにもタイプライブラリが必要です。TActiveXControl クラスは以下の動作も実装します。

コンテナ（サイト）への埋め込み

インプレースアクティベーション

持続性

イベント

プロパティページ

プロパティのブラウズ

ActiveX コントロールの作成についての詳細は，「ActiveX コントロールの作成」を参照してください。


See also1111063

TInterfacedObject

TComObject

TTypedComObject

TComObjectFactory

TTypedComObjectFactory

TAutoObject

TActiveXControl

TActiveForm

TOleContainer

ActiveX コンポーネント

ActiveX コントロールの作成

OLE オートメーションサーバーの作成


Creating ActiveX controls
Creating ActiveX controls1096001

Section topics 	参照

この章では，ActiveX コントロールの作成方法，および ActiveX コントロールウィザードを使用して，VCL コントロールを ActiveX コントロールに変換する方法について説明します。

ActiveX コントロールは，ActiveX コントロールをサポートするどのホストにでも統合できるソフトウェアコンポーネントです。このホストには，Paradox for Windows，Delphi，Delphi アプリケーション，Visual dBASE，Borland C++Builder，Access，Visual Basic などや，MS Internet Explorer，Netscape Navigator といったインターネットブラウザなどがあります。ActiveForm は，Web アプリケーション化に使う専用の ActiveX コントロールです。ActiveForm の作成方法については「ActiveForm の作成」を参照してください。


Overview of ActiveX control creation
Overview of ActiveX control creation1096002

Section topics 	参照

ActiveX コントロールはいくつかの段階を経て作成します。

1.	ActiveX コントロールの基本形を形成する VCL コントロールを設計して作成します。詳細については「カスタムコントロールの作成」を参照してください。

2.	ActiveX コントロールウィザードを使って，VCL コントロールから ActiveX コントロールを作成します。

3.	必要であれば ActiveX プロパティページウィザードを使って，ActiveX コントロールのプロパティページを作成します。

4.	必要であればプロパティページを ActiveX コントロールに関連付けます。

5.	ActiveX コントロールをコンパイルして登録します。

6.	ターゲットになりうるすべてのアプリケーションで ActiveX コントロールをテストします。


Elements of an ActiveX control
Elements of an ActiveX control1096003

Section topics 	参照

ActiveX コントロールには多くの要素が含まれており，それぞれが特定の機能を実行します。これらの要素には，VCL コントロール，プロパティ，メソッド，イベント，関連付けられた 1 つまたは複数のタイプライブラリなどがあります。

VCL control1096004

Delphi の ActiveX コントロールは簡単にいうと，ActiveX コントロールをサポートしているアプリケーションとオブジェクトに割り当てられるようにした VCL コントロールです。ActiveX コントロールを作成する場合，VCL コントロールをまず設計または選択してから，そのコントロールで ActiveX を作らなければなりません。

Type library1096005

タイプライブラリには，ActiveX コントロールの新規型定義が入ります。ActiveX コントロールウィザードを使うと，タイプライブラリを自動的に作成できます。この型情報に従って，ホストアプリケーションは ActiveX コントロールの機能を認識します。コントロールを設計する場合タイプライブラリ情報は .TLB ファイルと，Pascal 変換の入った対応する Pascal ファイルに格納されます。ActiveX コントロールを構築すると，タイプライブラリ情報は自動的にリソースとして .OCX または .EXE にコンパイルされます。

Properties, methods, and events1096006

VCL コントロールのプロパティ，メソッド，イベントは ActiveX コントロールのプロパティ，メソッド，イベントになります。

プロパティは色やラベルなどの属性である

メソッドはコントロールに対するなんらかの動作の実行要求である

イベントはコントロールからコンテナへのなんらかの事象の通知である

Property page1096007

プロパティページを使うと，ActiveX コントロールのユーザーがそのプロパティを表示して編集できるようになります。開発者は複数のプロパティを 1 ページにグループ化することも，1 ページを使ってダイアログボックスに似たインターフェースをプロパティ用に提供することもできます。プロパティページの作成方法についての詳細は，「プロパティページ」を参照してください。


Creating an ActiveX control
Creating an ActiveX control1096008

Section topics 	参照

ActiveX コントロールは，ActiveX コントロールウィザードが ActiveX ラッパーを VCL コントロールに配置して，そのオブジェクトを含んだ OCX を構築したときに作成されます。ActiveX ラッパーは，コントロールの機能を他のオブジェクトやサーバーにエクスポーズします。

ActiveX コントロールウィザードを使う前に，ActiveX コントロールを作成する VCL コントロールを特定しておかなければなりません。


Using the ActiveX control wizard
Using the ActiveX control wizard1096009

Section topics 	参照

ActiveX コントロールを作成する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択して［ActiveX］ページが開きます。

3.	［ActiveX コントロール］アイコンを選択し，［OK］を選択します。［ActiveX コントロールウィザード］ダイアログボックスが表示されます。

4.	コントロールを［VCL クラス名(C)］ドロップダウンリストから選択します。

［ActiveX の名前(N)］および［ユニット名(U)］のデフォルト名が表示されます。［ユニット名(U)］には，ActiveX コントロールの動作を実装するコードが入っています。

ActiveX コントロールは ActiveX ライブラリプロジェクトに追加しなければなりません。ActiveX ライブラリプロジェクトが現在開いていない場合，［プロジェクト名(P)］を使うと ActiveX コントロールが追加される ActiveX ライブラリプロジェクトを指定できます。デフォルトでは新規プロジェクト名が示されます。

5.	以下の 2 つの ActiveX コントロールオプションを設定できます。

［設計時モードライセンスを追加(D)］

設計時モードライセンスを設定すると，ユーザーは，コントロールのライセンスキーを持っていないと設計の目的でコントロールを開くことができなくなります。［設計時モードライセンスを追加(D)］にチェックマークが付いていると，ウィザードによってコントロールのキーが作成され，プロジェクトと同名の .LIC ファイルに保存されます。コントロールのユーザーが開発環境内でコントロールを開くには，この .LIC ファイルのコピーが必要です。

プロジェクト内の，［設計時モードライセンスを追加(D)］にチェックマークが付いたコントロールごとに，.LIC ファイルに別々のキーエントリを持ちます。

［バージョン情報を追加(V)］

このオプションを設定すると，.OCX ファイルにバージョン情報が含まれます。このリソースをコントロールに追加すると，著作権やファイルの説明といったモジュール情報をコントロールでエクスポーズでき，ブラウザで確認できるようになります。バージョン情報を指定するには，［プロジェクト(P)｜オプション(O)］を選択して，［バージョン情報］ページを選択します。［バージョン情報］ページの各設定については，オンラインヘルプを参照してください。

メモ	Visual Basic 4.0 でコントロールを登録するには，バージョン情報が必要です。

［バージョンダイアログを追加(A)］

このボックスにチェックマークを付けると，プロジェクトにバージョン情報ボックスが含まれます。コントロールのユーザーは開発環境内でバージョン情報ボックスを表示できます。バージョン情報ボックスは別個のフォームであり，開発者が変更できます。デフォルトでは，ActiveX コントロール名，イメージ，著作権情報，［OK］ボタンがバージョン情報ボックスに含まれます。

6.	［OK］を選択します。

必要であれば ActiveX ライブラリプロジェクトが作成され，タイプライブラリ，フォーム，実装ユニットや，対応するすべてのタイプライブラリ宣言を含むユニットが作成されます。［バージョンダイアログ］にチェックマークが付いている場合，バージョン情報ボックスのフォームとユニットが作成され，プロジェクトに追加されます。

ウィザードは実装ユニットを生成し，ActiveX コントロール用に VCL コントロールのすべてのプロパティ，メソッド，イベントを実装します。必要に応じて，このファイルでメンバーの実装コードを変更できます。

Editing the type library1096010

タイプライブラリは ActiveX コントロールが明示するデータ型，インターフェース，メンバー関数，オブジェクトクラスのすべての情報を定義します。ActiveX コントロールウィザードが作成した新規タイプライブラリの名前は，拡張子が .TLB のプロジェクト名です。インターフェースのプロパティとメソッドを指定するための便利なツールとして，タイプライブラリエディタがあります。

タイプライブラリエディタを使ってタイプライブラリを編集する手順は次のとおりです。

1.	［ファイル(F)｜開く(O)］を選択します。

2.	.TLB ファイルの名前を入力し，［開く(O)］を選択します。

タイプライブラリエディタが呼び出されます。

3.	VCL コントロールに含まれていないかまたは自動的に変換されなかったプロパティとメソッドを，ここでタイプライブラリに追加できます。

メモ	ActiveX コントロールがコントロールをデータベース対応にするメカニズムは VCL コントロールとは異なるので，データに関連するプロパティは変換されません。ActiveX のデータベース対応プロパティをいくつかコントロールに追加するとよいでしょう。

ActiveX コントロールウィザードは ActiveX コントロールのプロパティとメソッドを定義するデュアルインターフェースと，ActiveX コントロールが送出できるイベントを指定するディスパッチインターフェースを作成します。デュアルインターフェースとディスパッチインターフェースについての詳細は「OLE と ActiveX の概要」を参照してください。

タイプライブラリとタイプライブラリエディタについての詳細は「タイプライブラリの操作」を参照してください。

Adding additional members1096011

補足のプロパティ，メソッド，イベントを ActiveX コントロールに追加する手順は次のとおりです。

1.	［編集(E)｜インターフェースに追加(O)］を選択します。メニュー項目を利用できるようにするため，ActiveX コントロールの実装ユニットを開いて選択しておかなければなりません。

［インターフェースに追加］ダイアログボックスが開きます。

2.	［インターフェース］ドロップダウンリストの［プロパティ/メソッド］または［イベント］を選択します。項目には，そのメンバーが追加されるインターフェースの名前が示されます。

3.	プロパティ，メソッド，イベントの宣言を入力します。たとえば，VCL コントロールの TButton を使って ActiveX コントロールを作成した場合，次のプロパティを追加できます。

property Top:integer;

［構文の支援］チェックボックスにチェックマークを付けている場合，各段階で入力時にヒントが表示されユーザーの入力を補助します。

4.	［OK］を選択します。

宣言は自動的に ActiveX コントロールの実装ユニット，タイプライブラリ（.TLB）ファイル，タイプライブラリユニットに追加されます。

Adding properties1096012

インターフェースはデュアルインターフェースなので，プロパティは .PAS ファイルのアクセスメソッド read および write を使って実装されます。ウィザードは，Top プロパティ用に以下の宣言を実装ユニットに追加します。

property Caption: Integer read Get_Caption write Set_Caption;

アクセスメソッド read および write の宣言，実装内容は以下のようになります。このプロパティでは，取得側メソッドと設定側メソッドの宣言と実装コードは次のようになります。

function Get_Caption: Integer; safecall;

procedure Set_Caption(Value: Integer); safecall;

function TButtonX.Get_Caption: Integer;

begin

  Result := FDelphiControl.Caption;

end;

procedure TButtonX.Set_Caption(Value: Integer);

begin

  FDelphiControl.Caption := Value;

end;

これらのメソッドは safecall として宣言されます。つまり，エラーと例外処理用に OLE 表記法に従ったコードを自動的に実装します。

インターフェース実装メソッドは動作を VCL コントロールに伝えるだけです。OLE のデータ型を Delphi のネイティブな型に変換するためのコードを追加する必要がある場合もあります。

Adding methods1096013

メソッドを追加すると，その機能を追加するために空の実装コードが追加されます。たとえば，次のメソッドを追加した場合，

procedure Move;

次の宣言とコードがユニットに追加されます。

procedure Move; safecall;

procedure TButtonX.Move;

begin

end;

メモ	オートメーションインターフェースメソッドは safecall と宣言されるので，これらのメソッド用に OLE 例外コードを実装する必要はありません。Delphi の例外を捕らえて OLE のエラー情報構造体と戻りコードに変換するコードを Delphi コンパイラが自動的に safecall メソッド本体のまわりに生成します。

Adding events1096014

ActiveX コントロールはコンテナにイベントを送出できます。ActiveX コントロールが送出できるイベントを指定するために，イベントを追加します。イベントを追加すると，以下の項目が作成されます。

ディスパッチインターフェースの宣言と実装のエントリ（実装ユニット内）

procedure KeyPressEvent(Sender: TObject; var Key: Char);

procedure TButtonX.KeyPressEvent(Sender: TObject; var Key: Char);

var

  TempKey: Smallint;

begin

  TempKey := Smallint(Key);

  if FEvents <> nil then FEvents.OnKeyPress(TempKey);

  Key := Char(TempKey);

end;

イベントインターフェースのタイプライブラリエントリ。その属性ページでは dispinterface にチェックマークが付いている

Object Pascal バージョン（タイプライブラリのインターフェースソースファイル内）

オートメーションインターフェースとは違って，イベントインターフェースは ActiveX コントロールのインターフェースリストに追加されません。イベントを受け取るのは ActiveX コントロールではなく，コンテナです。

Adding a property page1096015

プロパティページを追加して，ActiveX コントロールのユーザーがコントロールの属性の更新と編集を行えるようにできます。プロパティページの作成方法については，「プロパティページの作成」を参照してください。

たとえば，前述のボタンコントロールの場合，プロパティページをコントロールに関連付ける手順は次のとおりです。

1.	ActiveX コントロールの実装ユニットにある DefinePropertyPages メソッドの実装コードに，パラメータとしてプロパティページの GUID を付けて DefinePropertyPages を呼び出します。プロパティページの GUID はプロパティページユニットにあります。次に例を示します。

procedure TButtonX.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage);

begin

  DefinePropertyPage(Class_PropertyPage1);

end;

2.	プロパティページユニットを ActiveX コントロールの実装ユニットの uses 節に追加します。

3.	プロパティページユニットで，コントロールのデータでプロパティページを更新するコードを UpdatePropertyPage メソッドに追加します。たとえば，プロパティページの編集ボックスにコントロールの Caption プロパティのテキストが入っている場合，次のコードを追加すると，コントロールの Caption プロパティが変更されたときに必ず編集ボックスが更新されるようになります。

procedure TPropertyPage1.UpdatePropertyPage;

begin

  Edit1.Text := OleObject.Caption

end;

4.	プロパティページユニットで，最新のプロパティページデータでコントロールを更新するコードを UpdateObject メソッドに追加します。たとえば，プロパティページの編集ボックスにコントロールの Caption プロパティのテキストが入っている場合，次のコードを追加すると，ユーザーがプロパティページの適用ボタンを選択したときに必ずプロパティページのデータでコントロールが更新されるようになります。

procedure TPropertyPage1.UpdateObject;

begin

  OleObject.Caption := Edit1.Text;

end;

Building and registering the server1096016

プロジェクトを構築すると，ActiveX コントロールの入った .OCX ファイルが作成されます。Visual Basic，Delphi，Paradox for Windows などのほかのアプリケーションが ActiveX コントロールを使えるようにするため，この ActiveX コントロールを登録しなければなりません。ActiveX コントロールを登録すると，そのエントリが Windows レジストリに追加されます。

ActiveX コントロールを登録するには，［実行(R)｜ActiveX サーバーの登録(A)］を選択します。

システムから ActiveX コントロールを削除したい場合は，まず Windows レジストリからそのコントロールのエントリを削除するようにしてください。

ActiveX コントロールの登録を解除するには，［実行(R)｜サーバーの削除(U)］を選択します。


Testing the ActiveX control
Testing the ActiveX control1096017

Section topics 	参照

Delphi でコントロールをテストするには，そのコントロールをパッケージに追加し，ActiveX コントロールとしてインポートします。これにより，そのコントロールがコントロールパレットに追加されます。アプリケーションのフォームにコントロールを配置すれば，他のコンポーネントと同様にテストできます。

コントロールは，そのコントロールを使うすべてのターゲットアプリケーションでもテストする必要があります。

ActiveX コントロールをデバッグするには，［実行(R)｜実行時引数(P)］を選択し，［ホストアプリケーション(A)］編集ボックスにクライアント名を入力します。

パラメータはホストアプリケーションに渡されます。［実行(R)｜実行(R)］を選択すると，ホストアプリケーションまたはクライアントアプリケーションが実行され，コントロール内にブレークポイントを設定できます。


Deploying the ActiveX control
Deploying the ActiveX control1096018

Section topics 	参照

ActiveX コントロールは Web サーバーで配布することができます。ActiveX コントロールプロジェクトを配布するには，Web 配布用のオプションを適切に設定し，プロジェクトをコンパイルしなければなりません。このダイアログボックスのオプションについての詳細は「ActiveX の Web での配布」を参照してください。


See also1096019

TActiveXControl

ActiveX コンポーネント

OLE と ActiveX の概要

タイプライブラリの使い方

ActiveX の Web での配布

ActiveForm の作成

コンポーネントの作成の概要

プロパティページの作成


Creating ActiveForms
Creating ActiveForms1098001

Section topics 	参照

この章では，ActiveForm の作成方法について説明します。ActiveForm は Delphi フォームの一種で，ActiveX コントロールでもあります。ActiveForm を Web で配布する場合，ActiveForm への参照を含み，ActiveForm の位置を指定する HTML ページが作成されます。Microsoft Internet Explorer 3.0 や Netscape Navigator 4.0 などの Web ブラウザ内から表示して実行できます。Web ブラウザ内では，ActiveForm はスタンドアロンの Delphi フォームと同じように動作します。ActiveForm には，カスタム VCL コントロールなどの VCL または ActiveX のどのコンポーネントでも入れることができます。

Delphi では，ActiveForm を作成しやすくするために Active Form ウィザードを提供しています。ActiveForm ウィザードで以下のものを作成します。

ActiveForm を入れる ActiveX ライブラリプロジェクト

カスタマイズ可能な ActiveForm

ActiveForm プロジェクトを設計し，ActiveX ライブラリにコンパイルすると，その ActiveForm プロジェクトを Web サーバーで配布できます。このとき，ActiveForm への参照の入ったテスト用 HTML ページが作成されます。


Creating an ActiveForm
Creating an ActiveForm1098002

Section topics 	参照

ActiveForm を作成する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択します。［Active フォーム］アイコンにフォーカスがある状態で表示されます。

3.	［OK］を選択します。［Active フォームウィザード］ダイアログボックスが表示されます。

［ActiveX の名前(N)］および［ユニット名(U)］にはデフォルトの名前が示されます。これらの名前は変更可能です。このユニットには，ActiveForm の動作を実装するコードが含まれます。

ActiveForm は ActiveX ライブラリプロジェクトに追加しなければなりません。現在 ActiveX ライブラリプロジェクトを開いていない場合は，［プロジェクト名(P)］で ActiveForm コントロールを追加する ActiveX ライブラリプロジェクトを指定できます。デフォルトでは新規プロジェクト名が示されます。

4.	設定できる ActiveX コントロールオプションは以下の 3 つです。

［設計時モードライセンスを追加(D)］

［バージョン情報を追加(V)］

［バージョンダイアログを追加(A)］

これらのオプションについては「ActiveX コントロールの作成」を参照してください。

5.	［OK］を選択します。

必要であれば ActiveX ライブラリプロジェクトが作成され，タイプライブラリ，フォーム，実装ユニットや，対応するすべてのタイプライブラリ宣言を含むユニットが作成されます。［バージョンダイアログを追加］にチェックマークが付いている場合，バージョン情報ボックスのフォームとユニットが作成され，プロジェクトに追加されます。

Delphi によって実装ユニットが生成され，TActiveForm のプロパティ，メソッド，イベントが ActiveForm に実装されます。

6.	現在のプロジェクトが ActiveX ライブラリでない場合， ActiveX ライブラリプロジェクトを新たに作成するかどうかを決めるためのダイアログボックスが表示されます。

ActiveForm は ActiveX ライブラリに入ります。したがって，ActiveForm を入れる ActiveX ライブラリプロジェクトをまず作成しておかなければなりません。

7.	［OK］を選択します。

空白フォームが ActiveX ライブラリプロジェクトに追加され，必要であれば ActiveX ライブラリプロジェクトが作成されます。この時点で，希望どおりにコントロールの追加やフォームの設計ができます。フォームの構築についての詳細は『ユーザーズガイド』を参照してください。


Publishing properties
Publishing properties1098003

Section topics 	参照

Visual Basic などの開発環境で ActiveForm を開いた場合，デフォルトでは，ActiveForm 上のコントロールのプロパティは表示されません。これらのプロパティは，開発環境で変更できるようにパブリッシュに設定できます。

プロパティをパブリッシュに設定する手順は次のとおりです。

1.	実装ユニットをエディタで開いているときに［編集(E)｜インターフェースに追加(O)］を選択します。

2.	［インターフェース］ドロップダウンリストの［プロパティ/メソッド］を選択します。

3.	エクスポーズするコントロールのプロパティの宣言を入力します。たとえば，ボタンコントロールの Caption プロパティの場合は次のように入力します。

property MyButtonCaption: WideSt ring;

4.	［OK］を選択します。

これで，実装ユニットに get メソッドと set メソッドが追加されます。

5.	コントロールのプロパティを取得および設定するコードをメソッドに追加します。たとえば，前述のボタンコントロールでは次のようなコードになります。

function TActiveFormX.Get_MyButtonCaption: WideString;

begin

  Result := Button1.Caption;

end;

procedure TActiveFormX.Set_MyButtonCaption(const Value: WideString);

begin

  Button1.Caption := Value;

end;

ActiveForm は ActiveX コントロールなので，ActiveForm に関連付けられたタイプライブラリがあり，ActiveForm にプロパティやメソッドを追加できます。この追加方法については「ActiveX コントロールの作成」を参照してください。


Deploying the ActiveForm
Deploying the ActiveForm1098004

Section topics 	参照

ActiveForm の設計を完了したら，その ActiveForm を Web サーバーで配布できます。ActiveForm プロジェクトを配布するには，Web 配布用のオプションを適切に設定し，プロジェクトをコンパイルしなければなりません。このダイアログボックスのオプションについての詳細は，「ActiveX の Web での配布」を参照してください。


See also1098005

TActiveForm

ActiveX の Web での配布

ActiveX コントロールの作成

ActiveX コンポーネント


ActiveX Web Deployment
ActiveX Web Deployment1097001

Section topics 	参照

ActiveForm または ActiveX コントロールの作成を終了したら，それを Web サーバーで配布できます。

Deploying ActiveForms and ActiveX controls1097002

ActiveForm または ActiveX コントロールプロジェクトを配布するためには，Web 配布用のオプションを適切に設定し，プロジェクトをコンパイルしなければなりません。このダイアログのオプションについての詳細は，「Web 配布用のオプションの設定」を参照してください。

コントロールを配布する手順は次のとおりです。

1.	［プロジェクト(P)｜Web 配布オプション(W)］を選択して，［Web 配布オプション］ダイアログボックスを開きます。

2.	［プロジェクト］ページで［配布先ディレクトリ］に Web サーバー上での ActiveForm の .DLL の位置を示すパスを設定します。ローカルパス名または UNC パスを指定できます。

3.	［配布先 URL］に Web サーバー上での ActiveForm の DLL の位置を示す URL を設定します（ファイル名を除く）。

4.	［HTML ディレクトリ］に ActiveForm への参照の入った HTML ファイルの位置を示すパスを設定します。標準パス名または UNC パスを指定できます。

5.	［OK］を選択します。

6.	［プロジェクト(P)｜Web 配布(D)］を選択します。

これによって，ActiveX ライブラリ（.OCX）が作成されます。このライブラリには ActiveForm または ActiveX コントロールが含まれます。

ActiveX ライブラリ（.OCX）は手順 2 の［配布先ディレクトリ］の位置に置かれます。HTML ファイルはプロジェクトファイルと同じ名前ですが，拡張子が .HTM になり，手順 4 の［HTML ディレクトリ］の位置に作成されます。HTML ファイルには手順 3 で指定した位置にある OCX への URL による参照が入っています。

7.	Web ブラウザを呼び出し，作成した HTML ページを表示します。

この HTML ページを Web ブラウザで表示すると，作成したフォームまたはコントロールがブラウザ内で組み込みのアプリケーションとして表示され，実行されます。


Setting Web Deployment Options
Setting Web Deployment Options1097003

Section topics 	参照

［Web 配布オプション］ダイアログボックスの設定は，現在開いている ActiveX プロジェクトにだけ作用します。［Web 配布オプション］ダイアログボックスを表示するには，［プロジェクト(P)｜Web 配布オプション(W)］を選択します。［Web 配布オプション］ダイアログボックスには，［デフォルト］のラベルが付いたチェックボックスが含まれます。このコントロールにチェックマークを付けると，［Web 配布オプション］ダイアログボックスの［プロジェクト］，［パッケージ］，［追加ファイル］，［コード署名］の各ページの現在の設定が，デフォルトオプションとして保存されます。

Delphi のオリジナルのデフォルト設定を復元するには，レジストリキー \HKEY_CURRENT_USER\Software\Borland\Delphi\3.0\Deployment\Defaults を削除してください。


CAB file compression
CAB file compression1097004

Section topics 	参照

Web 配布用のオプションには，.OCX，パッケージ，およびサポートファイルをキャビネットファイルとして配布するための設定が含まれています。キャビネットは単独のファイルで，通常はファイル拡張子 .CAB が付き，圧縮ファイルをファイルライブラリに格納します。キャビネット圧縮によってファイルのダウンロード時間を大幅に削減できます（70% まで）。インストール時に，ブラウザはキャビネットに格納されたファイルを圧縮解除し，ユーザーのシステムにコピーします。配布する各ファイルは，圧縮された .CAB ファイルにもできます。


Code signing
Code signing1097005

Section topics 	参照

Web 配布用のオプションには，.OCX と，任意のパッケージおよびサポートファイルにコード署名するための設定が含まれています。コード署名によって，コントロールのユーザーは，そのコントロールを誰が記述したかを確認し，コード署名後にそのコードが変更されていないことを確認できます。配布するそれぞれのファイルにコード署名することが可能です。署名データはファイルを変更しません。コード署名を行うと，デジタル署名が生成され，ファイルに追加されます。

メモ	Delphi はコード署名に必要な資格認定とプライベートキーを提供しません。これらのファイルの取得方法についての情報は，Microsoft から入手できます。


Packages
Packages1097006

Section topics 	参照

ActiveForm または ActiveX コントロールを配布する場合，配布の一環として必要な各パッケージファイルに対して，配布用のオプションを指定できます。これらのパッケージは，それぞれコード署名して .CAB ファイルに入れることができます。Delphi に付属するパッケージはボーランドの署名によってすでにコード署名されています。


.INF file
.INF file1097007

Section topics 	参照

ActiveForm または ActiveX コントロールがパッケージや補助ファイルとともに配布される場合，.INF ファイルが自動的に作成されます。このファイルは，OCX を実行するためにダウンロードし設定する必要がある種々のファイルを指定します。.INF ファイルの構文では，ダウンロードするパッケージまたは補助ファイルを示す URL を指定できます。


Option combinations
Option combinations1097008

Section topics 	参照

次の表は，パッケージ，CAB ファイル圧縮，コード署名といった Web 配布用の各オプションについて，さまざまな組み合わせを選択した場合の結果をまとめたものです。

パッケージやサポートファイルの選択	CAB ファイル圧縮の選択	コード署名の選択	結果
しない	しない	しない	.OCX ファイル
しない	しない	する	.OCX ファイル
しない	する	しない	.OCX ファイルを含む CAB ファイル
しない	する	する	.OCX ファイルを含む CAB ファイル
する	しない	しない	.INF ファイル，.OCX ファイル，サポートファイルおよびパッケージ
する	しない	する	.INF ファイルを含む .CAB ファイル，.OCX ファイル，サポートファイルおよびパッケージ
する	する	しない	.INF ファイル，.OCX ファイルを含む .CAB ファイル，サポートファイルおよびパッケージのそれぞれに対する CAB ファイル
する	する	する	.INF ファイルを含む .CAB ファイル，.OCX ファイルを含む .CAB ファイル，サポートファイルおよびパッケージのそれぞれに対する CAB ファイル


Project page
Project page1097009

Section topics 	参照

［プロジェクト］ページでは，ファイルの位置および URL の指定と，プロジェクトに対するその他の配布用のオプションの設定が可能です。［プロジェクト］ページのオプションは，.OCX ファイルまたは OCX を含む .CAB ファイルに適用され，そのプロジェクトとともに配布されるパッケージおよび補助ファイルのデフォルトオプションになります。

ディレクトリおよび URL	意味
配布先ディレクトリ	Web サーバー上の .OCX ファイルの位置を示すパス。標準パス名または UNC パスを指定できる
配布先 URL	Web サーバー上の .OCX ファイルの位置を示すパスの URL
HTML ディレクトリ	OCX への参照を含む HTML ファイルの位置を示すパス。標準パス名または UNC パスを指定できる
メモ	これらはパスのみで，完全なファイル名ではありません。

一般オプション	意味
Use CAB file compression	特に指定されない限り，OCX，必要なパッケージおよび補助ファイルを圧縮する
Include file version number	［プロジェクト(P)｜オプション(O)｜バージョン情報］に含まれるバージョン番号を含める
Auto increment release number	［プロジェクト(P)｜オプション(O)｜バージョン情報］に含まれるプロジェクトリリース番号を自動的にインクリメントする
Code sign project	.OCX または OCX を含む .CAB ファイルにコード署名する。特に指定されない限り，配布する DLL または補助ファイルにもコード署名する
Deploy required packages	チェックマークを付けた場合，必要なパッケージがプロジェクトとともに配布される
Deploy additional files	チェックマークを付けた場合，［追加ファイル］ページで指定された補助ファイルがプロジェクトとともに配布される


Packages page
Packages page1097010

Section topics 	参照

［パッケージ］ページでは，プロジェクトによって使われるパッケージがどのように配布されるかを指定できます。プロジェクトが使うパッケージごとに，個別の設定を指定できます。

Packages used by this project1097011

特定のパッケージの設定を変更するには，［プロジェクトで使用するパッケージ］リストボックスでパッケージを選択し，必要に応じて設定を変更します。

CAB options1097012

オプション	意味
Compress in a separate CAB	パッケージに対して単独の .CAB ファイルを作成する（デフォルト）
Compress in a project CAB	パッケージを .CAB プロジェクトファイルに含める
Output options1097013

出力オプションは，パッケージがバージョン情報を持つかどうか，コード署名されるかどうかを指定するために使います。

オプション	意味
Use file VersionInfo	パッケージファイル内のリソースからバージョン情報を取り出し，プロジェクトの .INF ファイルに挿入する
Code sign file	パッケージまたはパッケージを含む .CAB ファイルにコード署名する
Directory and URL options1097014

オプション	意味
Target URL（空白の場合,ファイルはターゲットマシン上にあるものと想定される）	Web サーバー上のパッケージの位置を示すURL。空白の場合，Web ブラウザはそのファイルがターゲットマシン上に存在するものと想定する。ターゲットマシン上にパッケージが見つからない場合，OCX のダウンロードは失敗する
Target directory（空白の場合,ファイルはサーバー上にあるものと想定される）	Web サーバー上のパッケージの位置を示すパス。標準パス名または UNC パスを指定できる。空白の場合，ファイルが存在し，上書きされないことが想定される


Additional Files page
Additional Files page1097015

Section topics 	参照

［追加ファイル］ページでは，ActiveX コントロールまたは ActiveForm とともに配布されるサポートファイルを指定できます。サポートファイルには .DLL ファイル，.INI ファイル，リソースなどがあります。

配布するファイルを追加するには，［追加(A)］ボタンをクリックします。ダイアログボックスが表示され，このダイアログボックスでファイルを参照したり，選択したりできます。追加する各ファイルは［プロジェクトに関連するファイル］リストボックスに追加されます。

Files associated with project1097016

特定のファイルの設定を変更するには，［プロジェクトに関連するファイル］リストボックスでファイルを選択し，必要に応じて設定を変更します。

CAB options1097017

オプション	意味
Compress in a separate CAB	ファイルに対して単独の .CAB ファイルを作成する（デフォルト）
Compress in a project CAB	ファイルを .CAB プロジェクトファイルに含める
Output options1097018

オプション	意味
Use file VersionInfo	ファイルに VersonInfo リソースが含まれる場合，ファイル内のリソースからバージョン情報を取り出し，プロジェクトの .INF ファイルに挿入する
Code sign file	ファイルまたはファイルを含む .CAB ファイルにコード署名する
Directory and URL options1097019

オプション	意味
Target URL（ファイルがターゲットマシン上に存在すると想定した場合は，空白にする）	Web サーバー上のファイルの位置を示す URL。空白にした場合，Web ブラウザはファイルがターゲットマシン上に存在すると想定する。ファイルがターゲットマシン上で見つからない場合，OCX のダウンロードは失敗する
Target directory（ファイルがサーバー上に存在すると想定した場合は，空白にする）	Web サーバー上のファイルの位置を示すパス。標準パス名または UNC パスを指定できる。ファイルが存在すると想定し，上書きされないようにする場合は，空白にする


Code Signing page
Code Signing page1097020

Section topics 	参照

［コード署名］ページにはデジタル署名を作成するときに使われる設定が含まれます。デジタル署名を作成する場合，選択した暗号ダイジェストアルゴリズムを使って，まずハッシュ値が作成されます。ハッシュ値はメッセージダイジェストとも呼ばれます。次に，プライベートキーを使ってこのハッシュ値に署名がされます。

プライベートキーと資格認定ファイルについては，Microsoft に問い合わせてください。

Required Information1097021

オプション	意味
Credentials file	このファイルを取得するには，Microsoft に連絡する
Private key	プライベートキーはそのオーナーだけが知り，署名を生成するために使われる。このファイルを取得するには，Microsoft に連絡する
Optional Information1097022

オプション	意味
Name of this application	Web ブラウザによって表示されるデジタル資格認定に表示させるアプリケーション名を，表示したいとおりに指定する
Application or company URL	製品または会社の Web ページへのリンクを提供する URL
Cryptographic digest algorithm1097023

次の表の中から暗号ダイジェストアルゴリズムをどちらか選択します。MD5 がもっとも一般的に使われるもので，デフォルトになります。ブラウザが一方のアルゴリズムをサポートしていない場合，もう一方を選択する必要があります。

アルゴリズム	意味
MD5	MD5 ハッシングアルゴリズムは RSA Data Security, Inc. によって開発された。このアルゴリズムでは 128 ビットのハッシュ値が生成される
SHA 1	SHA ハッシングアルゴリズムは National Institute of Standards and Technology（NIST）および National Security Agency（NSA）によって開発された。このアルゴリズムでは 160 ビットのハッシュ値が生成される


See also1097024

TActiveXControl

TActiveForm

Web 配布用のオプションの設定

プロパティページ


Creating property pages
Creating property pages1116001

Section topics 	参照

プロパティページを利用すると，Delphi や Visual Basic などの開発環境内で ActiveX コントロールのプロパティをユーザーにわかりやすい形式で表示したり編集できます。プロパティページダイアログボックスでは，コントロールのいくつものプロパティを同時に編集するためにグループ化したり，もっと複雑なプロパティにダイアログボックスのユーザーインターフェースを提供できます。

次のプロパティページで，ユーザーはマスク編集コントロールの EditMask プロパティを編集できます。このダイアログボックスには，ユーザーが選択できるサンプルマスクのリストと，コントロールに適用する前にマスクをテストするための場所があります。

プロパティページが設計モードの場合，［OK］，［キャンセル］，［適用(A)］の各ボタンとタブは表示されません。これらのボタンやタブは，Borland C++ Builder，Delphi，Visual Basic，Optima++，IntraBuilder，Paradox for Windows，PowerBuilder などの開発環境で ActiveX コントロールのプロパティを編集している場合は，プロパティページダイアログボックスによって自動的に追加されます。

開発者が設計してコントロールに接続する各プロパティページは，コントロールのプロパティページダイアログボックスの新しいタブとして表示されます。開発環境のオブジェクトインスペクタに個々のプロパティが表示される場合もあります。

プロパティページの作成はフォームの作成とほとんど同じです。ActiveX コントロールのプロパティに対応する編集ボックスなどのコントロールを追加できます。イベントやほかのコントロールは，フォームに追加するのと同じように追加できます。フォームの設計についての詳細は『ユーザーズガイド』を参照してください。

プロパティページを作成して ActiveX コントロールに接続するには以下の手順に従います。

1.	プロパティページを作成します。

2.	コントロールのプロパティをプロパティページに結び付けます。

3.	プロパティページと ActiveX コントロールを接続します。


Creating a property page
Creating a property page1116002

Section topics 	参照

プロパティページを作成するには以下の手順に従います。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択して［ActiveX］ページを開きます。

3.	［プロパティページ］アイコンを選択し，［OK］を押します。

プロパティページが表示されます。


Adding controls to the property page
Adding controls to the property page1116003

Section topics 	参照

ユーザーがプロパティページで編集するコントロールの各プロパティには，ユーザーがプロパティを更新できるコントロールが必要です。たとえば，Caption プロパティは Edit コントロールで更新できます。プロパティの適切なコントロールの選択についての詳細は『ユーザーズガイド』を参照してください。

前述のマスク編集プロパティページでは，マスク編集 ActiveX コントロールの EditMask プロパティが，プロパティページの編集ボックスに関連付けられています。

設計モードのマスク編集プロパティページ

ユーザーはリストボックスでサンプルマスクのリストから選択できます。マスク編集コントロールを使うと，ActiveX コントロールに適用する前にマスクをテストできます。コントロールは，フォームに追加するのと同じようにプロパティページに追加します。


Associating properties with a property page
Associating properties with a property page1116004

Section topics 	参照

必要なすべてのコントロールをプロパティページに追加したら，各コントロールを対応するプロパティに関連付けなければなりません。プロパティページを作成すると，プロパティページの実装ユニット内でプロパティページに 2 つのメソッドが追加されます。このメソッドは，UpdateObject と UpdatePropertyPage の 2つです。

以下の各手順は，前述のマスク編集プロパティページを使って説明します。

Updating the object1116005

ユーザーがプロパティページのプロパティのコントロールを編集するときにプロパティを更新するためのコードを UpdateObject に追加します。次のコードは，マスク編集 ActiveX コントロールの EditMask プロパティをプロパティページの［InputMask］編集ボックスから更新します。

procedure TPropertyPage1.UpdateObject;

begin

  { コントロールから OleObject を更新する }

  OleObject.EditMask := InputMask.Text;

end;

Updating the property page1116006

プロパティが何か別の方法で変更されるときにプロパティページのプロパティのコントロールを更新するためのコードを UpdatePropertyPage に追加します。次のコードは，EditMask プロパティから［InputMask］編集ボックスを更新します。

procedure TPropertyPage1.UpdatePropertyPage;

begin

  { OleObject からコントロールを更新する }

  InputMask.Text := OleObject.EditMask;

end;


Connecting a property page to an ActiveX control
Connecting a property page to an ActiveX control1116007

Section topics 	参照

ActiveX コントロールへプロパティページを接続する手順は次のとおりです。

1.	コントロールの実装ユニット内の DefinePropertyPage メソッドの実装に，パラメータとしてプロパティページの GUID 定数を付けて DefinePropertyPage を追加します。次に例を示します。

procedure TButtonX.DefinePropertyPages(DefinePropertyPage: TDefinePropertyPage);

begin

   DefinePropertyPage(Class_PropertyPage1);

end;

プロパティページの GUID 定数の Class PropertyPage1 は，プロパティページのユニットにあります。

2.	コントロール実装ユニットの uses 節にプロパティページユニットを追加します。


See also1116008


Creating OLE Automation servers
Creating OLE Automation servers1110001

Section topics 	参照

この章では，OLE オートメーションおよびオートメーションサーバーの作成方法について説明します。ユーザーは，オートメーションオブジェクトエキスパートを使ってオートメーションオブジェクトを作成して，Active X サーバーに追加することができます。

 OLE Automation1110002

OLE オートメーションは，オブジェクトが OLE によってそのプロパティ，メソッド，型を定義し，それらへのアクセスを可能にするための標準的なメカニズムです。OLE オートメーションオブジェクトは，OLE オートメーションをサポートするほかのオブジェクトやアプリケーションがプログラムによって制御できます。オートメーションオブジェクトは，タイプライブラリを通じて自身の機能を提供します。OLE オートメーションでは，OLE オートメーションをサポートするコントローラアプリケーション（Delphi，Visual Basic，Delphi アプリケーションなど）とオートメーションサーバー（アプリケーションまたはライブラリ）が必要です。

OLE オートメーションサーバーには，オブジェクトとコントロールが含まれます。OLE オートメーションサーバーはライブラリか実行可能ファイルのどちらかです。オートメーションサーバーはインプロセスとアウトオブプロセスの 2 種類あります。リモートサーバーは，インプロセスサーバーとアウトオブプロセスサーバー上に構築されます。

In-process servers1110003

インプロセスサーバーは，クライアントと同じプロセス空間で実行されるライブラリ（DLL）です。コントロールであるオートメーションオブジェクトもライブラリです。通常は .OCX の拡張子が付きますが必須ではありません。

ライブラリはオートメーションオブジェクトとコントロールの両方を実装できます。コントロールは単にイベント付きのオートメーションオブジェクトであり，このイベントはコンテナのイベントシンクにバインドできます。オートメーションオブジェクトはビジュアルではありませんが，コントロールは通常ビジュアルです。コントロールには，オートメーションオブジェクトにはない追加のルールとプロパティがあります。

インプロセスサーバーの方が関数呼び出しが速くなります。これは，同一プロセス内にあり，マーシャリングが必要ないからです。マーシャリングについての詳細は「OLE と ActiveX の概要」を参照してください。

Out-of-process servers1110004

アウトオブプロセスサーバーは実行可能ファイルであり，独自のプロセス空間で実行されます。ActiveX コントロールをアウトオブプロセスにすることはできません。実行可能ファイルは独自のプロセス空間内で実行されるので，オートメーションオブジェクトを使うためにクライアントはマーシャリングを使わなければなりません。マーシャリングはディスパッチインターフェースを使って実行されます。

Remote Servers1110005

リモートサーバーは，マシン境界を越えて通信するアウトオブプロセスサーバーです。オートメーションオブジェクトは，DCOM の現在のバージョンでは実行可能ファイルでなければなりませんが，DCOM の将来のバージョンではライブラリにもできます。OLEnterprise では，ライブラリでも実行可能ファイルでもオートメーションサーバーとして使えます。

Interfaces1110006

OLE オートメーションオブジェクトのプロパティ，メソッド，型は，OLE オートメーションインターフェースの IDispatch を通じてエクスポーズできます。詳細は第 36 章「OLE と ActiveX の概要」を参照してください。デュアルインターフェースを使って OLE オートメーションを実現することもできます。詳細は「OLE と ActiveX の概要」を参照してください。


OLE Automation compatible types
OLE Automation compatible types1110007

Section topics 	参照

デュアルインターフェースとディスパッチインターフェース内で宣言するメソッドの関数結果とパラメータの型は，OLE オートメーション互換型でなければなりません。OLE オートメーション互換の型を以下に示します。

定義済みの型 Smallint，Integer，Single，Double，Currency，TDateTime，WideString，IDispatch，WordBool，OleVariant，SCode，TColor，Byte，TSafeArray，IUnknown

タイプライブラリに定義された列挙型。OLE オートメーション互換列挙型は 16 ビット値として格納され，パラメータを渡すために Smallint 型の値として扱われる

OLE オートメーション保障のタイプライブラリに定義されたインターフェース型。つまり，IDispatch から派生し，OLE オートメーション互換型だけを含むインターフェース型

タイプライブラリに定義された dispinterface 型

IFont，IStrings，IPicture。以下のマッピングを行うヘルパーオブジェクトをインスタンス化しなければならない

IFont から TFont

IStrings から TStrings

IPicture から TPicture.

ActiveX コントロールと ActiveForm の各ウィザードは，必要であれば自動的にこれらのヘルパーオブジェクトを作成します。


Overview of Automation server creation
Overview of Automation server creation1110008

Section topics 	参照

新規のオートメーションサーバーはいくつかの段階を経て作成します。

1.	プロジェクトを作成するか，あるいはオートメーションオブジェクトに追加する既存のプロジェクトを開く

2.	オートメーションオブジェクトウィザードを使って，オートメーションオブジェクトを作成してプロジェクトに追加する

3.	タイプライブラリにプロパティ，メソッド，型を追加する

4.	プロパティとメソッドを実装する

5.	オートメーションサーバープロジェクトをコンパイルし，登録する

6.	サーバーをターゲットになりうるすべてのアプリケーションでテストおよびデバッグする

オートメーションオブジェクトはプロパティとメソッドを使ってその動作を実装し，タイプライブラリを使ってその機能をアプリケーションやその他のオブジェクトにエクスポーズします。

Type library1110009

タイプライブラリにはオブジェクトの型定義が入っています。オートメーションオブジェクトウィザードを使うと，タイプライブラリを自動的に作成できます。この型情報に従って，ホストアプリケーションはオブジェクトの機能を調べます。タイプライブラリ情報は .TLB ファイルと，Pascal 変換コードの入った .PAS ファイルに格納されています。.PAS ファイルは自動的に生成されるので，次に保存するときに変更内容は失われます。オートメーションサーバーを構築すると，タイプライブラリ情報は自動的にリソースとしてアプリケーションにコンパイルされます。

Properties and methods1110010

プロパティとメソッドは，オブジェクトをほかのアプリケーションやオブジェクトが問い合わせまたは制御できるようにします。

プロパティは名前や郵便番号などの属性である

メソッド（プロシージャまたは関数）はオブジェクトに対するなんらかの動作の実行要求である


Creating an Automation server
Creating an Automation server1110011

Section topics 	参照

オートメーションオブジェクトウィザードでは，オートメーションサーバーに追加する新しい OLE オートメーションオブジェクトを作成できます。

Creating the Automation server project1110012

新しいオートメーションオブジェクトを作成する場合，OLE オートメーションサーバーにそのオブジェクトを追加します。この OLE オートメーションサーバーは OCX または EXE の新規プロジェクトか既存のプロジェクトです。

新しいオートメーションサーバーライブラリプロジェクトを作成する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択します。

3.	［ActiveX ライブラリ］アイコンを選択し，［OK］を押します。

新しいオートメーションサーバーの実行可能プロジェクトを作成するには，［ファイル(F)｜アプリケーションの新規作成(T)］を選択します。

この手順に従えば，オートメーションサーバープロジェクトになるプロジェクトを作成して開くことができます。

Creating the automation object1110013

オートメーションオブジェクトウィザードを使用して新しいオートメーションオブジェクトを作成します。その際，以下の 2 つを指定します。

新規オブジェクトの名前

インスタンスの種類

ウィザードの機能は以下のとおりです。

新規ユニットの作成

プロパティ，メソッド，型を追加する .TLB ファイルの作成

TAutoObject から派生するクラスの定義

IDispatch インターフェースの定義

オートメーションオブジェクトを作成する手順を以下に示します。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］タブを選択して［ActiveX］ページを開きます。

3.	［オートメーションオブジェクト］アイコンを選択し，［OK］を選択します。

これにより［オートメーションオブジェクトウィザード］ダイアログボックスが開きます。

4.	［クラス名(C)］にオブジェクト名を入力します。

5.	［インスタンスの生成］ドロップダウンリストの［Multiple Instance］，［Single Instance］，［Internal］のいずれかを選択します（詳細は次の節を参照してください）。

6.	［OK］を選択します。

タイプライブラリエディタが開くので，エクスポーズするオートメーションオブジェクトのプロパティ，メソッド，型を追加できます。

Instancing1110014

新規オートメーションオブジェクトを作成する場合，複数インスタンス，単一インスタンス，内部のいずれかのオブジェクトにできます。

インスタンス化	意味
Multiple	複数のアプリケーションがオブジェクトに接続できることを指定する
Single	あるアプリケーションがオブジェクトに接続するとオブジェクトは見えなくなるため，ほかのアプリケーションがそのオブジェクトに接続できなくなることを指定する。このオプションは，通常はシングルドキュメントインターフェース（SDI）アプリケーションに使う
Internal	オブジェクトは内的にだけ作成できる。外部アプリケーションはこのオブジェクトのインスタンスを直接作成できない。たとえば，ワープロアプリケーションには，ドキュメントオブジェクトを作成するアプリケーションのメソッドを呼び出した場合にだけ作成できるドキュメントオブジェクトが含まれていることがある
Adding properties, methods, and enumeration types1110015

オートメーションオブジェクトウィザードを使うと新規 .TLB ファイルが作成されてタイプライブラリエディタで開きます。ここで，アプリケーションおよびオブジェクトにエクスポーズするオートメーションオブジェクトのプロパティ，メソッド，型を追加できます。

オートメーションオブジェクトのプロパティ，メソッド，列挙型を追加するにはタイプライブラリエディタを使います。タイプライブラリエディタを使って追加または編集できるのは，インターフェース，列挙型，プロパティ，メソッドです。「タイプライブラリの操作」を参照してください。

Enumeration types1110016

列挙型は整数定数シンボルの名前の付いたグループです。C 言語の列挙子と同様に，列挙子名はユニークでなければなりませんが，列挙子値はユニークである必要はありません。

オブジェクトに列挙型を追加する手順は次のとおりです。

1.	適切なインターフェースを選択し，ツールバーで［Enum］アイコンをクリックします。

列挙型がオブジェクトリストペインに追加されます。

2.	列挙型の名前を入力し，〔Enter〕を押します。

3.	オブジェクトリストペインで新規列挙型を選択し，［属性］ページを選択します。［名前］，［ヘルプ文字列］，［ヘルプコンテキスト］，［バージョン］などの属性を入力して変更します。GUID 値は変更しないでください。これらの値については，「タイプライブラリの操作」を参照してください。

4.	［メンバー］ページにタブで移動します。このページは空白です。［メンバー］ページに直接値を入力して，列挙型に追加します。たとえば，ボタンコントロールが使う DragMode 列挙型の［メンバー］ページに次の宣言を入力できます。

dmManual = 0;

helpstring 'dmManual';

dmAutomatic = 1;

helpstring 'dmAutomatic';

Properties1110017

プロパティは，オブジェクトの状態に関する情報（色またはフォントなど）を設定したり返したりするメンバー関数です。たとえば，ボタンコントロールのプロパティは次のように宣言できます。

property Caption: WideString;

プロパティをオブジェクトに追加する手順は次のとおりです。

1.	適切なインターフェースを選択し，ツールバーで［Property］アイコンをクリックします。

プロパティがオブジェクトリストペインに追加されます。

2.	プロパティの名前を入力し，〔Enter〕を押します。

3.	そのプロパティの［属性］ページの［Declaration］フィールドで，プロパティ名とその型を設定します。有効な値については，「タイプライブラリの操作」を参照してください。たとえば，次のように入力します。

property MyProperty: WideString;

4.	新規プロパティの［属性］ページにデフォルトの属性とフラグが表示されます。これらはプロパティに合わせて変更できます。

get メソッドと set メソッドがオブジェクトの実装ユニットに追加されます。

5.	オブジェクトのプロパティを取得および設定するコードを get メソッドと set メソッドに追加します。

Methods1110018

メソッドは手続きか関数のどちらかです。

新規メソッドをオブジェクトに追加する手順は次のとおりです。

1.	適切なインターフェースを選択し，ツールバーで［Method］アイコンをクリックします。

メソッドがオブジェクトリストペインに追加され，名前の追加を求められます。

2.	メソッドの名前を入力し，〔Enter〕を押します。

新規メソッドの［属性］ページにデフォルト属性が表示されます。これはメソッドに合わせて変更できます。これらの属性については，「タイプライブラリの操作」を参照してください。

プロパティとメソッドは，［メンバー］ページに直接入力しても追加できます。たとえば，インターフェースの［メンバー］ページに次のプロパティ宣言を入力できます。

procedure Click; dispid 1;

property Cancel: WordBool; dispid 2;

property Caption: WideString; dispid 3;

property BorderStyle: BorderStyle; dispid 4;

インターフェースの［Members］ページにメンバーを追加すると，それらのメンバーはオブジェクトリストペインに独立した項目として表示されます。どのメンバーにも独自の［属性］ページがあり，そこでそれぞれの新規メンバーの属性を変更できます。

［編集(E)｜インターフェースに追加(O)］を選択して，プロパティ，メソッド，型をタイプライブラリに追加することもできます。

Registering an in-process server1110019

オートメーションサーバーを登録すると，そのサーバーが Windows レジストリに追加され，コントロールが登録されてほかのアプリケーション（Visual Basic，Paradox for Windows など）が使えるようになります。

オートメーションサーバーを登録するには，［実行(R)｜ActiveX サーバーの登録(A)］を選択します。

オートメーションサーバーをシステムから削除する場合は，最初に Windows のレジストリからエントリを削除することをお勧めします。

オートメーションサーバーの登録を解除するには，［実行(R)｜ActiveX サーバーの削除(U)］を選択します。

Registering an out-of-process server1110020

アウトオブプロセスサーバーは，初めて実行したときに自動的に登録されます。［実行(R)｜実行時引数(P)］で開くダイアログボックスで/regserver を指定している場合は，単に登録だけが行われます。サーバーの登録を解除するには，/unregserver を指定します。

Testing and debugging the server1110021

新しい OLE オートメーションサーバーは，ターゲットになりうるすべてのアプリケーションでテストする必要があります。

実行可能（アウトオブプロセス）サーバーをデバッグする手順は次のとおりです。

1.	IDE のサーバー内でデバッグを開始します。統合デバッガの使い方については，『Object Pascal 言語ガイド』を参照してください。

2.	Delphi の外部でクライアントアプリケーションを実行します。

3.	IDE 内でブレークポイントを設定してから，クライアントアプリケーションと対話してブレークポイントで停止するのを待ちます。

インプロセスサーバー（DLL または OCX）をデバッグするには，［実行(R)｜実行時引数(P)］を選択し，［ホストアプリケーション(A)］編集ボックスにクライアント名を入力します。

パラメータはホストアプリケーションに適用されます。［実行(R)｜実行(R)］を選択すると，ホストまたはクライアントのアプリケーションが実行され，サーバー内にブレークポイントを設定できます


See also1110022

OLE と ActiveX の概要

タイプライブラリの使い方

ActiveX コンポーネント

ActiveX コントロールの作成


Working with type libraries
Working with type libraries1119001

Section topics

この章では，タイプライブラリエディタを使ってタイプライブラリを作成および編集する方法について説明します。タイプライブラリはデータ型，インターフェース，メンバー関数，オブジェクトクラスについての情報が入った OLE 複合ドキュメントファイルで，これらの情報は ActiveX コントロールまたは ActiveX サーバーによって明示されます。1119002

Using type libraries1119003

あるアプリケーションまたは OCX にタイプライブラリを入れると，そのタイプライブラリ内のオブジェクトについての情報がほかのアプリケーションやプログラミングツールで使えるようになります。ウィザードを使って ActiveX コントロールまたはオートメーションオブジェクトを作成すると，タイプライブラリも作成されます。

タイプライブラリには，以下の一部または全部を入れることができます。

データ型についての情報

インターフェースや CoClass などの，1 つまたは複数の OLE 要素の記述。これらの記述のそれぞれを通常型情報と呼ぶ

ほかのタイプライブラリから型記述への参照


Deploying type libraries
Deploying type libraries1119004

Section topics

ActiveX コントロールウィザードを使って ActiveX コントロールを作成した場合，コントロールを構築するとタイプライブラリが自動的にコンパイルされ，リソースとして OCX ファイルが作成されます。

タイプライブラリは以下のいずれかの形式で配布できます。

.OCX ファイル。ダイナミックリンクライブラリ（DLL）内のリソース。このリソースには，typelib 型と整数の ID が必要である。リソースコンパイラを使ってタイプライブラリを構築した場合，このリソースは次のようにリソース（.RC）ファイルに宣言しなければならない

1 typelib mylib1.tlb

2 typelib mylib2.tlb

1 つの OCX には複数のタイプライブラリリソースを入れることができます。アプリケーション開発者は，リソースコンパイラを使用して .TLB ファイルを .OCX に追加することができます。

.EXE ファイル内のリソース。このファイルには複数のタイプライブラリを入れることができる

スタンドアロンのバイナリファイル。タイプライブラリエディタが出力する .TLB ファイルはバイナリファイルになる


The Type Library editor
The Type Library editor1119005

Section topics 	参照

タイプライブラリエディタは，ActiveX コントロールと COM オブジェクトの型情報を調べて作成するツールです。この型情報は，スタンドアロンでタイプライブラリ（.TLB）ファイルに入れられるかリソースとして EXE または OCX に統合されて，オブジェクトとともに提供されます。

図にタイプライブラリエディタ内に開いている ActiveX の編集コントロールのタイプライブラリを示します。

タイプライブラリエディタの主な要素を以下に示します。

ツールバー

オブジェクトリストペイン

エラーログペイン

タイプライブラリ内のすべての要素についての［属性］ページ

タイプライブラリの［参照］ページ

インターフェース，COM クラス，インターフェースメンバー，および列挙型の［メンバー］ページ

以降の各節では，タイプライブラリエディタのユーザーインターフェースの各要素と，どのような型情報が提供されるかについて説明します。


Object list pane
Object list pane1119006

Section topics 	参照

オブジェクトリストペインには，ライブラリに示されているすべての要素とその型情報が一覧表示されます。一覧表示される要素には，インターフェース，ディスパッチインターフェース，CoClass，インターフェースのプロパティとメソッド，列挙型，構造体，共用体，型定義，モジュールがあります。これらの用語についての詳細は「OLE と ActiveX の概要」を参照してください。オブジェクトリストペインは展開可能な階層ツリーで，個々のインターフェースのメンバーはそのインターフェースの子として表示されます。

メモ	追加と変更ができるのは，インターフェース，ディスパッチインターフェース，CoClass，列挙型，プロパティ，メソッドだけです。タイプライブラリエディタでは，タイプライブラリに入っている構造体，共用体，型定義，モジュールの表示はできますが，編集はできません。

以下の色分けしたシンボルは，オブジェクトリスト（左）ペインのオブジェクトの左側に表示されます。

アイコン	意味
	タイプライブラリ。このアイコンを展開して，ほかのタイプライブラリ内の個々のデータ型，オブジェクト，型記述への参照を表示できる
	インターフェース記述
	ディスパッチインターフェース記述
	CoClass
	インターフェースのメソッド
	インターフェースのプロパティ
	列挙型
	構造体（書き込み禁止）
	共用体（書き込み禁止）
	型定義（書き込み禁止）
	モジュール（書き込み禁止）


Type library information
Type library information1119007

Section topics 	参照

オブジェクトリストペインでタイプライブラリを選択すると，［属性］ページと［参照］ページが利用可能になります。

Attributes page1119008

［属性］ページには，現在選択されているライブラリについての型情報が表示されます。メインのオブジェクトペインでタイプライブラリを選択すると，［属性］ページに以下の属性とフラグが表示されます。

属性	意味
名前	スペースも句読点記号もないタイプライブラリの記述名
GUID	グローバルにユニークな 128 ビットのインターフェース識別子
バージョン	複数のライブラリバージョンが存在する場合の特定のライブラリバージョン。Version には，ピリオドで区切った 1 対の 10 進整数，または単一の 10 進整数のいずれかを使える。1 対の整数のうちの最初のものは，インターフェースのメジャーバージョン番号になり，2 番目のものはインターフェースのマイナーバージョン番号になる。単一の整数を使うと，その整数はメジャーバージョン番号になる。メジャーバージョン番号とマイナーバージョン番号はどちらも，範囲が 0 から 65535 までの符号なし 8 ビット整数である
LCID	タイプライブラリと要素内のすべてのテキスト文字列に使われる単一の特定言語を表すロケール ID
ヘルプファイル	タイプライブラリに関連付けられたヘルプファイルの名前
ヘルプ文字列	ライブラリについての簡単な説明。なるべくヘルプ文字列を提供するようにする
ヘルプコンテキスト	ライブラリのヘルプコンテキスト ID
以下のフラグは，サーバーがほかのアプリケーションにどのように使われるかを指定します。

フラグ	意味
None	フラグなし
Restricted	ライブラリがマクロプログラマに使われないようにする
Control	コンテナサイトが追加の typelib または coclass を派生させるのに使うコントロールをライブラリが表すことを示す
Hidden	ライブラリは存在しているが，ユーザー向けブラウザに表示してはならないことを示す
Uses page1119009

エディタの［参照］ページには，タイプライブラリによって参照される別のタイプライブラリが一覧表示されます。

メインオブジェクトペインでタイプライブラリを選択すると［参照］ページに以下の列が表示され，選択したタイプライブラリによって参照されるタイプライブラリが一覧表示されます。

列	意味
Type Library	ほかのタイプライブラリへの参照
GUID	グローバルにユニークな，参照されるタイプライブラリの 128 ビットの識別子


Attributes for type information
Attributes for type information1119010

Section topics 	参照

以下の属性は，メインのオブジェクトペインで列挙型，インターフェース，ディスパッチインターフェース，CoClass，構造体，共用体，型定義，モジュールのどれかが選択された場合に表示されます。

属性	意味
Name	列挙型の名前
GUID	グローバルにユニークな 128 ビットのインターフェース識別子。これはオプションである
Help String	列挙型についての簡単な説明。なるべくヘルプ文字列を提供するようにする
Help Context	列挙型のヘルプコンテキスト ID
Version	複数の列挙型バージョンが存在する場合の特定の列挙型バージョン。Version には，ピリオドで区切った 1 対の 10 進整数，または単一の 10 進整数のいずれかを使える。1 対の整数のうちの最初のものは，インターフェースのメジャーバージョン番号になり，2 番目のものはインターフェースのマイナーバージョン番号になる。単一の整数を使うと，その整数はメジャーバージョン番号になる。メジャーバージョン番号とマイナーバージョン番号はどちらも，範囲が 0 から 65535 までの符号なし 8 ビット整数である
Parent Interface	インターフェースとオブジェクトのみ。このインターフェースの基本となるインターフェースの名前。インターフェースだけに適用される


Members page for an enumeration
Members page for an enumeration1119011

Section topics 	参照

このページには，列挙型の型定義が入ります。各列挙型要素のヘルプ文字列とヘルプコンテキストも入れることができます。

パネルでのベベルについての列挙型のサンプルエントリを次に示します。このエントリには列挙型要素ごとのヘルプ文字列も入っています。列挙型にはなるべくヘルプ文字列を提供するようにしてください。COM オブジェクトを使うアプリケーションは，ヘルプ文字列に依存することがあります。

bvNone = 0;

helpstring 'bvNone';

bvLowered = 1;

helpstring 'bvLowered';

bvRaised = 2;

helpstring 'bvRaised';


Interface and CoClass flags
Interface and CoClass flags1119012

Section topics 	参照

次のフラグは，メインオブジェクトペインでインターフェースまたは CoClass が選択されたときに［属性］ページに表示されます。

フラグ	有効	意味
Aggregatable	CoClass	クラスのメンバーを集約できることを表す
Application Object	CoClass	CoClass が（完全な EXE アプリケーションに関連付けられた）アプリケーションオブジェクトであることを表し，CoClass の関数とプロパティがこのタイプライブラリ内でグローバルに使用可能であることを表す
Can Create	CoClass	インスタンスは，CoCreateInstance で作成できる
Control	CoClass	CoClass が，コンテナサイトが追加のタイプライブラリまたは CoClass を派生させる派生元の OLE コントロールであることを表す
DispInterface	Interface	仮想テーブルを通じてはアクセスできず IDispatch.Invoke を通じてアクセスしなければならないオブジェクトのプロパティ，およびメソッドを表す
Dual	Interface	IDispatch を通じて，および仮想テーブルを通じて直接プロパティとメソッドをエクスポーズするインターフェースを表す
Hidden	すべて	インターフェースが存在するが，ユーザー向けブラウザには表示されないことを表す
Licensed	CoClass	適用先の CoClass がライセンスを受けていて，IClassFactory2 を使ってインスタンス化されなければならないことを表す
Non-extensible	Interface	インターフェースの記述にあるプロパティとメソッドだけが，IDispatch の実装に含まれていることを表す
Ole Automation	Interface	インターフェースが OLE オートメーション互換型だけを使えることを表す。dispinterface は必然的に OLE オートメーション互換なので，dispinterface にこのフラグを使うことはできない
Predefined	CoClass	クライアントアプリケーションは，この属性を持つオブジェクトの単一のインスタンスを自動的に作成する
Replaceable	CoClass	オブジェクトが IConnectionPointWithDefault をサポートする
Members page for an interface1119013

［メンバー］ページには，インターフェースのプロパティとメソッドを定義します。各メンバーには DispID も定義できます。次の例では，インターフェースに含まれるプロパティを定義しています。

property Caption: WideString; dispid 1;

property BevelInner: DAXPanelBevel; dispid 2;

property BevelOuter: DAXPanelBevel; dispid 3;

property BevelWidth: Integer; dispid 4;

property BorderWidth: Integer; dispid 5;

property WindowBorder: DAXBorderStyle; dispid 6;

property Font: Font; dispid 7;

次の例では，インターフェースに含まれるメソッドを定義しています。

procedure OnClick; dispid 1;

procedure OnEnter; dispid 2;

procedure OnExit; dispid 3;

procedure OnDblClick; dispid 4;

procedure OnKeyPress(var Key: Byte); dispid 5;

スクリプトファイルから TLB を構築するのに使う Microsoft インターフェース定義言語（IDL）では，ElemDesc を使って，プロセス間でレコード要素，パラメータ，関数の戻り値を転送するのに必要な情報を記述します。これには，PARAMFLAG NONE，PARAMFLAG FOUT，PARAMFLAG FRETVAL，PARAMFLAG FLCID，PARAMFLAG FOPT，PARAMFLAG FHASDEFAULT などのフラグが含まれます。

パラメータの型がポインタ型の場合，通常，タイプライブラリエディタはその型を var パラメータに変換します。タイプライブラリを保存すると，変数パラメータの関連付けられた ElemDesc の PARAMFLAG フラグ（PARAMFLAG FIN または PARAMFLAG FOUT）がマークされます。型の前にポインタが置かれている場合，ElemDesc の PARAMFLAG フラグ（PARAMFLAG FIN または PARAMFLAG FOUT）はマークされないことがよくあり，dispinterface の場合は PARAMFLAG フラグは通常は使われません。こういった場合，変数識別子の横に {none}，{lcid}，{optional}，{default <value>}，{in} などのコメントが付くことがあります。これらのコメントは，タイプライブラリの保存時に PARAMFLAG フラグが正しくマークされるように，タイプライブラリエディタによって自動的に追加されます。

PARAMFLAG LCID は，パラメータがロケール ID であることを表します。この属性を持てるパラメータは 1 つだけです。そのパラメータは out 属性ではなく in 属性を持っていなければならず，型が long でなければなりません。dispinterface では lcid 属性は使えません。

Members page for a CoClass1119014

CoClass を選択してオブジェクトのメンバーを表示すると，［メンバー］ページに以下の列が表示されます。

列	意味
Interface	CoClass が実装するインターフェースの名前
GUID	オブジェクトのメンバーインターフェースの GUID を表す
Source	メンバーがイベントのソースであることを表す
Default	インターフェースまたは dispinterface がデフォルトのプログラム可能インターフェースを表すことを示す。CoClass は最大 2 つのデフォルトメンバーを持てる。1 つはソースインターフェースまたは dispinterface を表し，もう 1 つはシンクインターフェースまたは dispinterface を表す
Restricted	項目をプログラマが使えないようにする。インターフェースのメンバーが restricted と default の属性を両方持つことはできない
default v-table	異なる 2 つのソースインターフェースをオブジェクトが持てるようにする
このウィンドウで右クリックしたときに表示されるコンテキストメニューを使用することにより，CoClass クラスに新しいインターフェースを追加できます。このメニューから CoClass に追加するインターフェースを選択できます。このリストには，現在のタイプライブラリに定義され，現在のタイプライブラリが参照するタイプライブラリにも定義されているインターフェースが表示されます。


Interface members
Interface members1119015

Section topics 	参照

Attributes page1119016

メインオブジェクトペインでインターフェースのプロパティまたはメソッドを選択すると，［属性］ページに以下の属性とフラグが表示されます。

属性	意味
Declaration	プロパティまたはメソッドの宣言
ID	ディスパッチ ID
Help String	プロパティまたはメソッドの説明の文字列を表す。通常は，項目を説明するタイトルが含まれる
Help Context	プロパティまたはメソッドのヘルプコンテキスト ID を表す
Property Tpe	プロパティが Read/Write，Read-only，Write-only，By Reference Only のいずれであるかを表す
フラグ	プロパティ 専用	識別子	意味
By Reference	はい	byref	プロパティを参照渡しする
Restricted	いいえ	restricted	プロパティまたはメソッドをプログラマが使えないようにする
Source	いいえ	source	イベントのソースであるオブジェクトまたは VARIANT をメンバーが返すことを表す
Bindable	はい	bindable	プロパティがデータのバインディングをサポートすることを表す
Request Edit	はい	requestedit	プロパティが OnRequestEdit 通知をサポートすることを表す
Display Bindable	はい	displaybind	ユーザーに対して表示されるプロパティがバインド可能であることを表す
Default Bindable	はい	defaultbind	オブジェクトをもっともよく表す単一のバインド可能なプロパティを表す。defaultbind 属性を持つプロパティは bindable 属性も持たなければならない。dispinterface 内の複数のプロパティに指定することはできない
Hidden	いいえ	hidden	プロパティが存在するが，ユーザー向けブラウザには表示されないことを表す
Default Collection  Element	はい	defaultcollelem	Visual Basic でのコードの最適化を許可する
UI Default	いいえ	uidefault	型情報メンバーがユーザーインターフェース内での表示用のデフォルトメンバーであることを表す
Non Browsable	はい	nonbrowsable	プロパティが，プロパティ値を表示しないオブジェクトブラウザには表示されるが，プロパティ値を表示するプロパティブラウザには表示されないことを表す
Replaceable	いいえ	replaceable	オブジェクトが IConnectionPointWithDefault をサポートする
Immediate Bindable	はい	immediatebind	フォーム上の個々のバインド可能なプロパティがこの動作を指定できる。このビットが設定されている場合，すべての変更が通知される。この新しいビットを有効にするには，bindable と requestedit の両方の属性ビットが設定されなければならない


Error log pane
Error log pane1119017

Section topics 	参照

タイプライブラリエディタにタイプライブラリをロードすると，OLE の型が Pascal の型に直接マップされないために変換エラーが発生する場合があります。タイプライブラリを保存またはロードすると，構文と変換のエラーや警告がエラーログペインに表示されます。

たとえば，整数へのポインタへのポインタは整数への変数ポインタにマップされますが，Pascal ではすべてのパラメータが名前付きの型でなければならないので，これは不正な型になります。不正な型を作成しないように，整数へのポインタへのポインタは変数ポインタに変換されます。これは完全な一致ではないので，タイプライブラリを保存すると元の型についての情報は失われます。エラーログにはこういった問題が表示され，これらの警告を訂正したり覚えておくことができます。


Valid types
Valid types1119018

Section topics 	参照

タイプライブラリエディタでは，タイプライブラリで表現可能で，Delphi でもっとも役に立つ型のサブセットを編集できます。C や C++ などのほかの言語に適しているいくつかの型は，タイプライブラリエディタでは編集できません。

タイプライブラリで有効な型は次のとおりです。OLE オートメーション互換の列は，OLE Automation フラグまたは DispInterface フラグにチェックマークが付いているインターフェースがその型を使えるかどうかを表します。

Pascal の型	OLE  バリアントの型	OLE  オートメーション互換性	説明
Smallint	VT_I2	あり	符号付き 2 バイト整数
Integer	VT_I4	あり	符号付き 4 バイト整数型
Single	VT_R4	あり	4 バイト実数
Double	VT_R8	あり	8 バイト実数
Currency	VT_CY	あり	通貨
TDateTime	VT_DATE	あり	日付
WideString	VT_BSTR	あり	バイナリ文字列
IDispatch	VT_DISPATCH	あり	IDispatch インターフェースへのポインタ
SCODE	VT_ERROR	あり	OLE エラーコード
WordBool	VT_BOOL	あり	True = -1，False = 0
Ole Variant	VT_VARIANT	あり	OLE バリアント
IUnknown	VT_UNKNOWN	あり	IUnknown インターフェースへのポインタ
Shortint	VT_I1	なし	符号付き 1 バイト整数
Byte	VT_UI1	あり	符号なし 1 バイト整数
Word	VT_UI2	なし *	符号なし 2 バイト整数
UNIT	VT_UI4	なし *	符号なし 4 バイト整数
Comp	VT_I8	なし	符号付き 8 バイト実数
Largeunit	VT_UI8	なし	符号なし 8 バイト実数
SYSINT	VT_INT	なし *	システム依存の整数（Win32 = Integer）
SYSUNIT	VT_UNIT	なし *	システム依存の符号なし整数
HResult	VT_HRESULT	なし	32 ビットエラーコード
Pointer	VT_PTR	なし	型なしポインタ
TSafeArray	VT_SAFEARRAY	なし	Safe 配列
PChar	VT_LPSTR	なし	Char へのポインタ
PWideChar	VT_LPWSTR	なし	WideChar へのポインタ
* Word，UINT，SYSINT，SYSUINT は，一部のアプリケーションでは OLE オートメーション互換の場合があります。

メモ	Byte（VT_UI1）はオートメーション互換ですが，多くのオートメーションサーバーはこの値を正しく処理しないので，Variant または OleVariant では使えません。

これらの Pascal 型のほかに，ライブラリに定義されているかまたは参照されるライブラリに定義されているインターフェースと型を，タイプライブラリ定義で使えます。

SafeArrays1119019

タイプライブラリエディタでは，SafeArray がコンポーネントの型を指定しなければなりません。たとえば，次のコードで SafeArray は Integer をコンポーネントの型として指定しています。

procedure HighLightLines(Lines: TSafeArray(Integer));

SafeArray のコンポーネントの型は OLE オートメーション互換型でなければなりません。Delphi のタイプライブラリ変換ユニットでは，コンポーネントの型は不要であるか，使えません。


Creating a new type library
Creating a new type library1119020

Section topics 	参照

新規タイプライブラリを作成する手順は次のとおりです。

1.	［ファイル(F)｜新規作成(N)］を選択して［新規作成］ダイアログボックスを開きます。

2.	［ActiveX］ページを選択して［ActiveX］ページを開きます。

3.	［タイプライブラリ］アイコンを選択します。

4.	［OK］を押します。

タイプライブラリエディタが開き，タイプライブラリの名前の入力が求められます。

5.	タイプライブラリ名を入力し，〔Enter〕を押します。

インターフェース，CoClass，列挙型，プロパティ，メソッドをタイプライブラリに追加できます。

Adding an interface to the type library1119021

インターフェースを追加する手順は次のとおりです。

1.	ツールバーの［Interface］アイコンをクリックします。

オブジェクトリストペインにインターフェースが追加されます。

2.	インターフェース名を入力し，〔Enter〕を押します。

新規インターフェースには，必要に応じて変更できるデフォルト属性が入ります。［メンバー］ページは空なので，インターフェースの目的に合ったプロパティとメソッドを追加できます。

Adding properties and methods to the type library1119022

インターフェースにインターフェースメンバーを追加する手順は次のとおりです。

1.	ツールバーでメンバーの追加先インターフェースを選択し，［Properties］アイコンまたは［Methods］アイコンをクリックします。

オブジェクトリストペインにインターフェースメンバーが追加され，名前の追加を求められます。

2.	メンバー名を入力し，〔Enter〕を押します。

新規メンバーの［属性］ページには，そのメンバーに合わせて変更できるデフォルト属性が入ります。

プロパティとメソッドを追加するには，直接［メンバー］ページに入力するという方法もあります。たとえば，インターフェースの［メンバー］ページには次のプロパティ宣言を入力できます。

property AutoSelect: WordBool; dispid 1;

property AutoSize: WordBool; dispid 2;

property BorderStyle: BorderStyle; dispid 3;

インターフェースの［メンバー］ページにメンバーを追加すると，それらのメンバーはオブジェクトリストペインに独立した項目として表示されます。どのメンバーにも独自の［属性］ページがあり，そこでそれぞれの新規メンバーの属性を変更できます。

Adding a CoClass to the type library1119023

タイプライブラリに CoClass を追加する手順は次のとおりです。

1.	ツールバーの［CoClass］アイコンをクリックします。

オブジェクトリストペインに CoClass が追加され，名前の追加を求められます。

2.	クラス名を入力し，〔Enter〕を押します。

新規クラスの［属性］ページには，そのクラスに合わせて変更できるデフォルト属性が入ります。［メンバー］ページは空白になります。メンバーを追加する手順は次のとおりです。

3.	新規クラスの［メンバー］ページを右クリックします。

選択可能なインターフェースのリストを含むコンテキストメニューが表示されます。このリストには，現在のタイプライブラリに定義され，現在のタイプライブラリが参照するタイプライブラリにも定義されているインターフェースが表示されます。

4.	クラスの実装先インターフェースをダブルクリックします。

そのインターフェースは，GUID などの属性とともにそのページに追加されます。

Adding an enumeration to the type library1119024

タイプライブラリに列挙型を追加する手順は次のとおりです。

1.	ツールバーの［Enum］アイコンをクリックします。

オブジェクトリストペインに列挙型が追加され，名前の追加を求められます。

2.	メンバー名を入力し，〔Enter〕を押します。

新規列挙型は空で，［属性］ページにはその列挙型に合わせて変更できるデフォルト属性が表示されます。その列挙型の［メンバー］ページは空白になります。

［メンバー］ページに直接入力して，その列挙型に値を追加します。たとえば，あるボタンコントロールが使う列挙型の［メンバー］ページに次の宣言を入力できます。

mbLeft = 0;

helpstring 'mbLeft';

mbRight = 1;

helpstring 'mbRight';

mbMiddle = 2;

helpstring 'mbMiddle';


Saving and registering type library information
Saving and registering type library information1119025

Section topics 	参照

タイプライブラリ情報は，OLE 複合ドキュメントファイルである .TLB ファイルに格納されます。Delphi では Pascal ファイルにもタイプライブラリ情報が格納されます。.PAS ファイルは，タイプライブラリのインターフェース，型，クラスの情報を含むユニットです。このファイルへの変更は次にタイプライブラリを保存すると無効になるので，このファイルは編集しないでください。

ウィザードを使って ActiveX コントロール，オートメーションオブジェクト，または Active Form を作成すると，実装ユニットとともに自動的にタイプライブラリが作成されます。タイプライブラリを保存または更新すると，実装ユニットが自動的に更新されます。

タイプライブラリエディタでタイプライブラリ情報を保存するには，次の 3 つの方法があります。

保存

更新

登録

Saving a type library1119026

タイプライブラリを保存すると，以下の 4 つの処理が行われます。

構文をチェックする

情報を .TLB ファイルに保存する

情報を PAS ファイルに保存する

タイプライブラリが Active Form，ActiveX コントロール，またはオートメーションオブジェクトに関連付けられている場合は，実装を更新するようにモジュールマネージャに通知する

タイプライブラリを保存するには，［ファイル(F)｜上書き保存(F)］を選択します。

Refreshing the type library1119027

タイプライブラリを更新すると，以下の 3 つの処理が行われます。

構文検査が実行される

Pascal のタイプライブラリファイルをメモリだけに再生する。ディスクには保存しない

タイプライブラリが Active Form，ActiveX コントロール，またはオートメーションオブジェクトに関連付けられている場合は，実装を更新するようにモジュールマネージャに通知する

タイプライブラリを更新するには，ツールバーの［更新］アイコンを選択します。

メモ	タイプライブラリの項目の名前を変更するかまたは項目を削除した場合，実装を更新すると重複するエントリが作成されることがあります。この場合，コードを正しいエントリに移動して，重複するエントリを削除しなければなりません。

Registering the type library1119028

タイプライブラリを登録すると以下のことが行われます。

構文検査が実行される

タイプライブラリの Windows レジストリにエントリを追加する

タイプライブラリを登録するには，ツールバーの［登録］アイコンを選択します。


See also1119029

OLE と ActiveX の概要


Working with sockets
Working with sockets1121001

Section topics 	参照

この章では，ソケットコンポーネントについて説明します。ソケットコンポーネントを使うと，TCP/IP および関連するプロトコルを使ってほかのシステムと通信するアプリケーションを作成できます。ソケットを使うと，実際のネットワークソフトウェアの詳細を意識せずにほかのマシンとの接続を通じて読み書きができます。ソケットは TCP/IP プロトコルに基づいた接続を提供しますが，Xerox Network System（XNS），DEC の DECnet プロトコル，Novell の IPX/SPX ファミリーなどの関連プロトコルとともに動作できるだけの一般性も備えています。

クアライアント/サーバー版の Delphi では，ほかのシステムとの間で読み書きを行うネットワークサーバーやクライアントアプリケーションを記述できます。サーバーやクライアントアプリケーションは，ハイパーテキスト転送プロトコル（HTTP）やファイル転送プロトコル（FTP）などの単一のサービス専用にするのが普通です。サーバーソケットは，こういったサービスのいずれかを提供するアプリケーションが，そのサービスを利用するクライアントアプリケーションとリンクできるようにします。クライアントソケットは，いずれかのサービスを利用するアプリケーションが，そのサービスを提供しているサーバーアプリケーションとリンクできるようにします。


Implementing services
Implementing services1121002

Section topics 	参照

ソケットは，ネットワークサーバーまたはクライアントアプリケーションを記述するのに必要な要素の一部を提供します。HTTP や FTP など，多くのサービスについてはサードパーティのサーバーを簡単に利用できます。一部のサービスはオペレーティングシステムにバンドルさえされていて，開発者が記述する必要はありません。ただし，サービスの実装形式を細かく制御したい場合や，アプリケーションとネットワーク通信をより緊密に統合したい場合，必要な特定のサービスを提供するサーバーがなければ，独自のサーバーまたはクライアントアプリケーションを作成することになります。たとえば，分散データセットを使って作業する場合，ほかのシステム上のデータベースと通信するための層を記述します。


Understanding service protocols
Understanding service protocols1121003

Section topics 	参照

ネットワークサーバーまたはクライアントを記述する前に，自分のアプリケーションが提供または利用するサービスを理解しておかなければなりません。サービスの多くで標準プロトコルが使われますが，作成するネットワークアプリケーションでこれらのプロトコルをサポートしなければなりません。HTTP や FTP，さらには finger や time まで含め，こういった標準的なサービスのネットワークアプリケーションを記述する場合，ほかのシステムとの通信に使われる各プロトコルをまず理解する必要があります。ネットワークアプリケーションの記述を始める前に，提供または利用しようとしている特定のサービスについてのマニュアルを参照してください。

ほかのシステムと通信するアプリケーションに新しいサービスを提供する場合，そのサービスのサーバーとクライアント用の通信プロトコルを設計することから始めます。どんなメッセージを送信するのか，それらのメッセージをどのように調整するのか，情報をどのようにコード化するのか，といった点を考慮します。

Communicating with applications1121004

ネットワークソフトウェアと，サービスを利用するアプリケーションとの間の層をネットワークサーバーまたはクライアントアプリケーションが提供することがよくあります。たとえば，HTTP サーバーは，コンテンツを提供したり HTTP 要求メッセージに応答する Web サーバーアプリケーションと，インターネットとの間に位置します。

ソケットは，ネットワークサーバーまたはクライアントアプリケーションとネットワークソフトウェアの間のインターフェースを提供します。開発者は，作成するアプリケーションとそのアプリケーションを使うアプリケーションとの間のインターフェースを用意しなければなりません。ユーザーは，サードパーティ製の標準的なサーバーの API（ISAPI など）をコピーしたり，独自の API を設計して公開したりできます。


Services and ports
Services and ports1121005

Section topics 	参照

ほとんどの標準的なサービスは，特定のポート番号に関連付けられることになっています。ポート番号についての詳細は後述します。当分は，ポート番号をサービスのコード番号であると考えてください。

標準的なサービスを実装する場合は，Delphi の Windows ソケットオブジェクトにサービスのポート番号を調べられるメソッドがあります。新しいサービスを提供する場合は，関連付けるポート番号を Windows 95 または NT のマシン上の SERVICES ファイルで指定できます。SERVICES ファイルの設定については，Windows ソケットに関する Microsoft のマニュアルを参照してください。


Describing socket connections
Describing socket connections1121006

Section topics 	参照

ソケットは，ネットワークアプリケーションがネットワーク上でほかのシステムと通信するための手段を提供します。各ソケットをネットワーク接続のエンドポイントとみなすことができます。以下の情報を持っています。

アプリケーションを実行するシステム

アプリケーションが認識するインターフェース

アプリケーションが接続に使用するポート

ソケット接続を完全に記述するには，接続の両端にある各ソケットのアドレスを指定しなければなりません。


Types of connections
Types of connections1121007

Section topics 	参照

ソケット接続はクライアント接続，リスニング（監視）接続，サーバー接続という基本的な 3 つの種類に分けられます。それぞれ，接続が開始された形式と，どのローカルソケットが接続されるかを表します。

Client connections1121008

クライアント接続は，ローカルシステム上のクライアントソケットをリモートシステム上のサーバーソケットに接続します。クライアント接続はクライアントソケットが開始します。まず，クライアントソケットが接続先のサーバーソケットを記述しなければなりません。次に，クライアントソケットはそのサーバーソケットを探し，サーバーが見つかると接続を要求します。サーバーソケットは接続をすぐには完了しない場合があります。サーバーソケットはクライアントからの要求のキューを管理し，時間ができたら接続を完了します。サーバーソケットがクライアント接続を受け入れると，接続先のサーバーソケットについての完全な記述がサーバーソケットからクライアントソケットに送信され，クライアントソケットが接続を完了します。

Listening connections1121009

サーバーソケットはクライアントを探しません。かわりに，クライアントの要求を待つ受動的な「半接続」を形成します。サーバーソケットはキューをリスニング接続に関連付け，クライアントの接続要求を受信するとその要求がキューに記録されます。サーバーソケットがクライアントの接続要求を受け入れると，実際には新しいソケットを形成してそのクライアントに接続します。これにより，ほかのクライアントの要求を受け入れられるようにリスニング接続を開いておくことができます。

Server connections1121010

リスニングソケットがクライアントの要求を受け入れると，サーバーソケットがサーバー接続を形成します。サーバーが接続を受け入れると，クライアントへの接続を完了するサーバーソケットの記述がそのクライアントに送信されます。クライアントソケットがこの記述を受信して接続を完了すると，接続が確立されます。

いったんクライアントソケットへの接続が完了すると，サーバー接続はクライアント接続と区別できなくなります。両方のエンドポイントが同じ機能を持ち，同じ種類のイベントを受信します。リスニング接続だけは根本的に異なり，単一のエンドポイントしか持ちません。


Describing the socket
Describing the socket1121011

Section topics 	参照

ソケット接続を作成する前に，ソケット接続のエンドポイントを形成するソケットを記述しておかなければなりません。情報の一部は，アプリケーションを実行するシステムから取得できます。たとえば，クライアントソケットのローカル IP アドレスを記述する必要はありません。この情報はオペレーティングシステムから取得できます。

提供しなければならない情報は，操作するソケットの種類に応じて異なります。クライアントソケットは接続したいサーバーを記述しなければなりません。リスニングサーバーソケットは，提供するサービスを表すポートを記述しなければなりません。

ソケット接続のエンドポイントの完全な記述には，IP アドレスとポート番号の両方が含まれます。


Describing the host
Describing the host1121012

Section topics 	参照

ホストは，ソケットを持つアプリケーションを実行しているシステムです。IP アドレスを指定することでソケットのホストを記述できます。IP アドレスは，インターネットのドット付き標準表記法で表した 4 つの数値（バイト）からなる次のような文字列です。

123.197.1.2

単一のシステムが複数の IP アドレスをサポートする場合があります。

IP アドレスは覚えにくく，書き間違いやすいものです。かわりに使えるのがホスト名です。ホスト名は IP アドレスのエリアスで，URL によく見られます。ドメイン名とサービスを含む次のような文字列です。

http://www.wSite.Com

ほとんどのイントラネットには，そのネット上の各システムの IP アドレスを表すホスト名が用意されています。Windows 95 と NT のマシンでは，ホスト名がない場合，HOSTS ファイルに名前を入力することでローカル IP アドレスのホスト名を作成できます。HOSTS ファイルについての詳細は，Windows ソケットに関する Microsoft のマニュアルを参照してください。

サーバーソケットはホストを指定する必要はありません。ローカル IP アドレスをシステムから読み出せます。ローカルシステムが複数の IP アドレスをサポートする場合，サーバーソケットは，すべての IP アドレスに対するクライアントの要求を同時に待ちます。サーバーソケットが接続を受け入れると，クライアントソケットがリモート IP アドレスを提供します。

クライアントソケットは，リモートホストのホスト名か IP アドレスのどちらかを提供してリモートホストを指定しなければなりません。

Choosing between a host name and an IP address1121013

ほとんどのアプリケーションでは，ホスト名を使ってシステムを指定します。ホスト名の方が覚えやすく，誤記を見つけやすくなります。さらに，サーバーによっては，特定のホスト名に関連付けられたシステム（IP アドレス）が変更されることがあります。ホスト名を使うと，クライアントソケットは，ホスト名が表す抽象的なサイトが新しい IP アドレスに移行した場合でもそのサイトを探し出せます。

ホスト名がわからない場合，クライアントソケットは IP アドレスを使ってサーバーシステムを指定しなければなりません。IP アドレスを指定してサーバーシステムを指定した方が速やかにサーバーシステムを探し出せます。ホスト名を指定した場合，ソケットは，そのホスト名に関連付けられた IP アドレスを検索しないとサーバーシステムを探し出せません。


Using ports
Using ports1121014

Section topics 	参照

ソケット接続の相手側のシステムを見つけるのに十分な情報が IP アドレスで提供されますが，そのシステムのポート番号も必要です。ポート番号がないと，システムが一度に 1 つの接続しか形成できません。ポート番号はユニークな識別子であり，各接続に別々のポート番号を与えることによって，単一のシステムが同時に複数の接続に対応できるようになります。

前述の説明では，ポート番号はネットワークアプリケーションが実装するサービスの数字コードであるとしました。実際は，クライアントソケットがリスニングサーバー接続を見つけ出せるように，リスニングサーバー接続が自らを固定のポート番号で利用可能にするための取り決めにすぎません。サーバーソケットは，提供しているサービスに関連付けられたポート番号で接続要求を待ちます。サーバーソケットがクライアントソケットとの接続を受け入れると，異なる任意のポート番号を使う別のソケット接続がそのサーバーソケットによって作成されます。これにより，サービスに関連付けられたポート番号でリスニング接続が継続して接続要求を待つことができます。

クライアントソケットは任意のローカルなポート番号を使います。ほかのソケットがクライアントソケットを見つけ出す必要はないからです。クライアントソケットは，サーバーアプリケーションを見つけられるように，接続先のサーバーソケットのポート番号を指定します。目的のサービス名を指定することで間接的にポート番号を指定する場合がよくあります。


Using socket components
Using socket components1121015

Section topics 	参照

Delphi には 2 つのソケットコンポーネントがあり，これらのコンポーネントを使うと，ネットワークアプリケーションがほかのマシンとの接続を形成でき，その接続を通じて情報を読み書きできます。これらのソケットコンポーネントにはそれぞれ Windows ソケットオブジェクトが関連付けられています。Windows ソケットオブジェクトは実際のソケット接続のエンドポイントを表します。ソケットコンポーネントは，Windows ソケットオブジェクトを使って Windows ソケットの API 呼び出しをカプセル化します。そのため，接続の確立やソケットメッセージの管理についての詳細を Delphi アプリケーションで考慮する必要はありません。

Windows ソケットの API 呼び出しを操作したい場合，または Delphi が開発者にかわって作成する接続の詳細をカスタマイズしたい場合は，Windows ソケットオブジェクトのプロパティ，イベント，メソッドを使います。


Using client sockets
Using client sockets1121016

Section topics 	参照

アプリケーションを TCP/IP クライアントに変えるには，フォームまたはデータモジュールにクライアントソケットコンポーネント（TClientSocket）を追加します。クライアントソケットでは，接続したいサーバーソケットとそのサーバーに提供させたいサービスを指定できます。必要な接続を記述しておくと，クライアントソケットコンポーネントを使ってサーバーとの接続を完了できます。

各クライアントソケットコンポーネントは，接続のクライアントエンドポイントを表す単一のクライアント Windows ソケットオブジェクト（TClientWinSocket）を使います。

Specifying the desired server1121017

クライアントソケットコンポーネントには，接続したいサーバーシステムとポートを指定できる数多くのプロパティがあります。Host プロパティを使うと，ホスト名でサーバーシステムを指定できます。ホスト名がわからない場合，またはサーバーをできるだけ速やかに見つけたい場合は，Address プロパティを使ってサーバーシステムの IP アドレスを指定できます。ホスト名か IP アドレスのどちらかを必ず指定しなければなりません。両方とも指定した場合，クライアントソケットコンポーネントはホスト名を使います。

サーバーシステムに加えて，クライアントソケットが接続するサーバーシステム上のポートを指定しなければなりません。サーバーのポート番号は，Port プロパティを使って直接指定することも，Service プロパティを使って目的のサービス名を指定して間接的に指定することもできます。ポート番号とサービスを両方とも指定すると，クライアントソケットコンポーネントはサービス名を使います。

Forming the connection1121018

クライアントソケットコンポーネントのプロパティを設定して，接続したいサーバーを記述してあれば，Open メソッドを呼び出すことで実行時に接続を形成できます。アプリケーションの起動時に自動的に接続を形成したい場合は，オブジェクトインスペクタを使って設計時に Active プロパティを True に設定します。

Getting information about the connection1121019

いったんサーバーソケットとの接続が完了したら，クライアントソケットコンポーネントに関連付けられたクライアント Windows ソケットオブジェクトを使って，接続に関する情報を取得できます。クライアント Windows ソケットオブジェクトにアクセスするには，Socket プロパティを使います。この Windows ソケットオブジェクトには，クライアントソケットとサーバーソケットが接続のエンドポイントを形成するのに使ったアドレスとポート番号を確認できるプロパティがあります。SocketHandle プロパティを使うと，Windows ソケットの API 呼び出しを行うときに使うソケット接続のハンドルを取得できます。Handle プロパティを使うと，ソケット接続からメッセージを受信するウィンドウにアクセスできます。ASyncStyles プロパティでは，そのウィンドウハンドルが受信するメッセージの種類を確認できます。

Closing the connection1121020

ソケット接続を通じたサーバーアプリケーションとの通信を終了したら， Close メソッドを呼び出して接続を閉じることができます。接続がサーバー側から閉じられる場合もあります。その場合，OnDisconnect イベントで通知されます。


Using server sockets
Using server sockets1121021

Section topics 	参照

アプリケーションを TCP/IP サーバーに変えるには，フォームまたはデータモジュールにサーバーソケットコンポーネント（TServerSocket）を追加します。サーバーソケットでは，提供するサービスを指定したり，クライアントの要求を待つのに使うポートを指定できます。クライアントの接続要求を待ち，受け入れるのにサーバーソケットコンポーネントを使えます。

各サーバーソケットコンポーネントは，リスニング接続のサーバーエンドポイントを表す単一のサーバー Windows ソケットオブジェクト（TServerWinSocket）を使います。サーバーが受け入れるクライアントソケットとのアクティブな接続ごとのサーバーエンドポイントを表すサーバークライアント Windows ソケットオブジェクト（TServerClientWinSocket）も使います。

Specifying the port1121022

サーバーソケットがクライアントの要求を待つには，サーバーが接続要求を待つポートを指定しておかなければなりません。このポートは Port プロパティで指定できます。特定のポート番号に関連付けられることになっている標準的なサービスをサーバーアプリケーションで提供する場合は，Service プロパティを使ってポート番号を間接的に指定できます。ポート番号の設定では誤記を見逃しやすいので，Service プロパティを使った方がよいでしょう。Port プロパティと Service プロパティを両方とも指定すると，サーバーソケットはサービス名を使います。

Listening for client requests1121023

サーバーソケットコンポーネントのポート番号を設定したら，Open メソッドを呼び出すことで実行時にリスニング接続を形成できます。アプリケーションの起動時に自動的にリスニング接続を形成したい場合は，オブジェクトインスペクタを使って設計時に Active プロパティを True に設定します。

Forming connections to clients1121024

リスニングサーバーソケットコンポーネントは，クライアントの接続要求を受信すると，その要求を自動的に受け入れます。これが行われるたびに，OnClientConnect イベントで通知されます。

Getting information about connections1121025

いったんサーバーソケットでリスニング接続を開いたら，サーバーソケットコンポーネントに関連付けられたサーバー Windows ソケットオブジェクトを使って，接続に関する情報を取得できます。サーバー Windows ソケットオブジェクトにアクセスするには，Socket プロパティを使います。この Windows ソケットオブジェクトには，サーバーソケットコンポーネントが受け入れた，クライアントソケットとのアクティブなすべての接続について確認できるプロパティがあります。SocketHandle プロパティを使うと，Windows ソケットの API 呼び出しを行うときに使うソケット接続のハンドルを取得できます。Handle プロパティを使うと，ソケット接続からメッセージを受信するウィンドウにアクセスできます。

クライアントアプリケーションとのアクティブな接続は，それぞれサーバークライアント Windows ソケットオブジェクト（TServerClientWinSocket）によってカプセル化されます。サーバー Windows ソケットオブジェクトの Connections プロパティを使うと，これらのすべてにアクセスできます。これらのサーバークライアント Windows ソケットオブジェクトには，クライアントソケットとサーバーソケットが接続のエンドポイントを形成するのに使ったアドレスとポート番号を確認できるプロパティがあります。SocketHandle プロパティを使うと，Windows ソケットの API 呼び出しを行うときに使うソケット接続のハンドルを取得できます。Handle プロパティを使うと，ソケット接続からメッセージを受信するウィンドウにアクセスできます。ASyncStyles プロパティでは，そのウィンドウハンドルが受信するメッセージの種類を確認できます。

Closing the connection1121026

リスニング接続を閉じたい場合は，Close メソッドを呼び出します。Close メソッドを呼び出すと，クライアントアプリケーションへの，開いているすべての接続が閉じ，受け入れられなかった保留中の接続がすべて解除されます。その後，サーバーソケットコンポーネントが新しい接続を受け入れないようにリスニング接続が閉じます。

クライアントがサーバーソケットとの個々の接続を閉じると，OnClientDisconnect イベントで通知されます。


Reading and writing over socket connections
Reading and writing over socket connections1121027

Section topics 	参照

ほかのマシンとのソケット接続を形成するのは，それらの接続を通じて情報の読み書きができるようにするためです。何の情報をいつ読み書きするかは，ソケット接続に関連付けられたサービスによって異なります。

ソケットを通じての読み書きは非同期に行われるため，ネットワークアプリケーション内のほかのコードの実行は妨げられません。これを非ブロッキング接続といいます。ブロッキング接続を形成することもできます。ブロッキング接続では，アプリケーションは，読み書きが完了するまで待ってからコードの次の行を実行します。


Non-Blocking connections
Non-Blocking connections1121028

Section topics 	参照

クライアントソケットの場合，非ブロッキング接続を形成するには，ClientType プロパティを ctNonBlocking に設定します。接続が非ブロッキングの場合，接続の相手側のサーバーがその接続を通じて情報の読み書きを試みると，ソケットに通知されます。これらの通知に対しては，OnRead または OnWrite の各イベントハンドラで応答できます。

サーバーソケットの場合，非ブロッキング接続を形成するには，ServerType プロパティを stNonBlocking に設定します。非ブロッキングのクライアント接続と同様に，接続の相手側のクライアントが接続を通じて情報の読み書きを試みると，非ブロッキングサーバーに通知されます。これらの通知に対しては，OnClientRead または OnClientWrite の各イベントハンドラで応答できます。

Reading and writing events1121029

ソケット接続に関連付けられた Windows ソケットオブジェクトは，読み書きの各イベントハンドラへのパラメータとして提供されます。この Windows ソケットオブジェクトには，接続を通じて読み書きができる数多くのメソッドがあります。

ソケット接続から読み出すには，ReceiveBuf メソッドまたは ReceiveText メソッドを使います。ReceiveBuf メソッドを使う前に ReceiveLength メソッドを使って，接続の相手側のソケットが送信しようとしているバイト数を確認します。

ソケット接続へ書き込むには，SendBuf，SendStream，または SendText の各メソッドを使います。ソケットを通じて情報を書き込んだ後はソケット接続が不要になる場合は，SendStreamThenDrop メソッドも使えます。SendStreamThenDrop を使うと，ストリームから読み出せる情報をすべて書き込んだ後にソケット接続が閉じます。SendStream メソッドまたは SendStreamThenDrop メソッドを使う場合，ストリームオブジェクトを解放しないでください。接続が閉じると，ソケットが自動的にストリームを解放します。

メモ	SendStreamThenDrop が閉じるのは個々のクライアントへのサーバー接続です。リスニング接続ではありません。


Blocking connections
Blocking connections1121030

Section topics 	参照

接続がブロッキングの場合，ソケットは，ソケット接続からの通知を受動的に待たずに，接続を通じた読み書きを開始しなければなりません。いつ読み書きするかを接続の自分側で管理しなければならない場合，ブロッキングソケットを使います。

クライアントソケットの場合， ブロッキング接続を形成するには，ClientType プロパティを ctBlocking に設定します。クライアントアプリケーションがほかに何をするかに応じて，読み書き用に新しい実行スレッドを作成するとよいでしょう。こうするとアプリケーションは，接続を通じての読み書きが完了するのを待っている間に，ほかのスレッド上でコードの実行を続けられます。

サーバーソケットの場合，ブロッキング接続を形成するには，ServerType プロパティを stThreadBlocking に設定します。ブロッキング接続では，接続を通じて情報が読み書きされるのをソケットが待っている間はほかのすべてのコードの実行が停止されるので，ServerType が stThreadBlocking の場合，サーバーソケットコンポーネントは必ずそれぞれのクライアント接続用に新しい実行スレッドを生成します。

Using threads with blocking connections1121031

ブロッキング接続を使って読み書きする場合，クライアントソケットは自動的には新しいスレッドを生成しません。情報の読み書きが終わるまでクライアントアプリケーションが何もすることがない場合は，これで問題ありません。しかし，読み書きの間もユーザーに応答しなければならないユーザーインターフェースをアプリケーションが持っている場合は，読み書き用に別のスレッドを生成した方がよいでしょう。

サーバーソケットがブロッキング接続を形成する場合，あるクライアントが接続を通じて読み書きを完了するまでほかのクライアントが待たなくてもすむように，サーバーソケットはクライアント接続ごとに別々のスレッドを必ず生成します。サーバーソケットは TServerClientThread オブジェクトを使って各接続の実行スレッドを実装します。このサーバークライアントスレッドは，実行されると接続の相手側のクライアントが接続を通じて書き込みを試みているかどうかを調べ，そうであれば OnClientRead イベントを生成します。クライアントが接続上で書き込みを試みていない場合は，サーバーが書き込みを開始するように OnClientWrite イベントを生成します。

Using TWinSocketStream1121032

非ブロッキング接続とブロッキングサーバー接続は，接続で読み書きの準備ができたことを表すイベントを受信します。その後，イベントハンドラで Windows ソケットオブジェクトのメソッドを使って，実際の読み書きができます。

ただし，ブロッキングクライアント接続は，接続の相手側のソケットで読み書きの準備ができたことを自分で確認しなければなりません。接続に対する読み書きに TWinSocketStream オブジェクトを使う場合，読み書きのタイミングを調整できるメソッドがあります。サーバーソケットの準備ができるまで待機するには，WaitForData メソッドを呼び出します。

TWinSocketStream を使って読み書きする場合，20 秒経過しても読み書きが完了しないと，ストリームがタイムアウトになります。このタイムアウトが発生しても，接続の切断のためにソケットアプリケーションが無限に停止してしまうことにはなりません。このため，ブロッキングサーバーソケットでも読み書きに TWinSocketStream を使うとよいでしょう。

メモ	非ブロッキング接続では，TWinSocketStream は使えません。


Responding to socket events
Responding to socket events1121033

Section topics 	参照

この章では，ソケットコンポーネントが受信するいくつかのイベントについて説明しました。ソケット接続を通じた読み書きをいつ開始したらよいかをソケットに伝えるために，非ブロッキングソケットとブロッキングサーバーソケットで生成されるイベントがありました。また，サーバーが接続を終了するときにクライアントソケットが受信する OnDisconnect イベントや，クライアントが接続を終了するときにサーバーソケットが受信する OnClientDisconnect イベントもありました。

それ以外に，クライアントソケットとサーバーソケットは両方とも，接続からエラーメッセージを受信すると OnError イベントを生成します。ソケットコンポーネントも，接続を開いてから完了するまでの間にいくつものイベントを受信します。ソケットを開く手順をアプリケーションで制御しなければならない場合や，接続が形成されたらアプリケーションが読み書きを開始しなければならない場合，これらのイベントに応答するイベントハンドラを記述します。


Error events
Error events1121034

Section topics 	参照

クライアントソケットとサーバーソケットは両方とも，接続からエラーメッセージを受信すると OnError イベントを生成します。これらのエラーメッセージに応答するには OnError イベントハンドラを記述します。OnError イベントハンドラには，エラー発生時にソケットが実行しようとしていたことについての情報と，エラーメッセージに示されたエラーコードが渡されます。エラーに対して OnError イベントハンドラで応答でき，ソケットが例外を生成しないようにエラーコードを 0 に変更できます。


Client events
Client events1121035

Section topics 	参照

クライアントソケットが接続を開くと，次のイベントが発生します。

1.	サーバーソケットを探そうと試みる前に OnLookup イベントが発生します。この時点では，探し出すサーバーソケットを変更するために Host，Address，Port，Service の各プロパティを変更することはできません。Socket プロパティを使うとクライアント Windows ソケットオブジェクトにアクセスでき，この Windows ソケットオブジェクトの SocketHandle プロパティを使うと，ソケットのクライアントプロパティを変更する Windows API 呼び出しを行えます。たとえば，クライアントアプリケーションにポート番号を設定したい場合，サーバークライアントに接続する前にこの時点で設定します。

2.	Windows ソケットが設定され，イベント通知のために初期化されます。

3.	サーバーソケットが見つかった後に OnConnecting イベントが発生します。この時点で，Socket プロパティを通じて利用できる Windows ソケットオブジェクトが，接続の相手側を形成するサーバーソケットについての情報を提供できます。これが接続に使われた実際のポートと IP アドレスを取得できる最初の機会です。このポートと IP アドレスは，接続を受け入れたリスニングソケットのポートや IP アドレスとは異なる場合があります。

4.	サーバーが接続要求を受け入れ，クライアントソケットが接続要求を完了します。

5.	接続が確立された後，OnConnect イベントが発生します。ソケットがただちに接続を通じて読み書きを開始しなければならない場合は，そのために OnConnect イベントハンドラを記述します。


Server events
Server events1121036

Section topics 	参照

サーバーソケットコンポーネントは，リスニング接続とクライアントアプリケーションへの接続という 2 種類の接続を形成します。これらの各接続が形成される間に，サーバーソケットはイベントを受信します。

Events when listening1121037

リスニング接続が形成される直前に，OnListen イベントが発生します。この時点で，Socket プロパティを使ってサーバー Windows ソケットオブジェクトを取得できます。この Windows ソケットオブジェクトの SocketHandle プロパティを使うと，接続要求を待つためにソケットが開く前にそのソケットに変更を加えることができます。たとえば，サーバーが接続要求を待つのに使う IP アドレスを制限したい場合は，OnListen イベントハンドラの中で制限します。

Events with client connections1121038

サーバーソケットがクライアントの接続要求を受け入れると，次のイベントが発生します。

1.	サーバーソケットが OnGetSocket イベントを生成して，接続のサーバーエンドポイントを形成するソケットの Windows ソケットハンドルを渡します。TServerClientWinSocket の下位オブジェクトをカスタマイズして提供したい場合， OnGetSocket イベントハンドラの中でこの下位オブジェクトを作成でき，その下位オブジェクトが TServerClientWinSocket のかわりに使われます。

2.	OnAccept イベントが発生し，新しい TServerClientWinSocket オブジェクトをイベントハンドラに渡します。ここで初めて，TServerClientWinSocket のプロパティを使ってクライアントへの接続のサーバーエンドポイントに関する情報を取得できます。

3.	ServerType が stThreadBlocking の場合，OnGetThread イベントが発生します。TServerClientThread の下位オブジェクトをカスタマイズして提供したい場合，OnGetThread イベントハンドラの中でこの下位オブジェクトを作成でき，その下位オブジェクトが TServerClientThread のかわりに使われます。

4.	ServerType が stThreadBlocking の場合，スレッドの実行が開始されると OnThreadStart イベントが発生します。スレッドの初期化を実行したい場合，またはスレッドが接続を通じて読み書きを開始する前に Windows ソケットの API 呼び出しを行いたい場合，OnThreadStart イベントハンドラを使います。

5.	クライアントが接続を完了し，OnClientConnect イベントが発生します。非ブロッキングサーバーを含めて，ソケット接続を通じた読み書きは，この時点で開始するとよいでしょう。


See also1121039

TClientSocket

TClientWinSocket

TServerSocket

TServerWinSocket

TServerClientWinSocket

TServerClientThread

TWinSocketStream

Internet コンポーネント