カスタムコンポーネントの作り方はC+Builderのヘルプにも説明されていますが、特に知識のない状態で読むと全体像がつかみにくく、わかりにくいのが欠点です。また、一般の書籍にもある程度は記載されていると思いますが、すでに絶版となって入手困難なものも多いのが現状です。あるいは載っていてもカスタムコンポーネントの作成については、ほんのさわり程度しか触れておらず、例として載っているコンポーネントも、実用性や作りたいと思うものからはかけ離れていて、十分な情報が得られないことが多いと思います。
このページが少しでも役に立てればと思いますが、説明の不十分なところもあるかと思いますので、必ずC++Builderのヘルプと併用してください。
おしながき.
全体の流れ.
コンポーネントパレットにも組み込めるカスタムコンポーネント作成の全体的な手順を示します。以下のとおりでなくてもいい部分もあるのですが、説明の都合もありますので。
カスタムコンポーネント用のプロジェクトを新規作成
↓
通常のアプリケーションとして作成、基本的な機能をデバッグ
↓
コンポーネントへ変換、デバッグ
↓
プロパティエディタ・コンポーネントエディタを作成
プロジェクトの作成.
ベースとなるクラスの選択.
コンポーネントは1つのクラスとして実装し、TComponentから継承して作成する必要があります。しかしすべてのコンポーネントが直接TComponentから派生させなければならないわけではなく、VCLにすでに用意されているTComponentから派生した多くのクラスをペースにして作成することができます。
ベースにするクラスにはどれを選べばいいか最初はわからないと思いますが、作成するコンポーネントの機能に最も近いものが基準になります。コンポーネントパレットにあるものでもいいのですが、VCLには「TCustom〜」という名前のクラスが多くあり、それらは他のクラスを派生させるためのものですから、これらも検討するといいものが見つかることがあります。
コンポーネントのユニット作成.
お決まりのプロジェクトの作成です。「ファイル−新規作成−その他」からコンポーネントを選択すると、次のダイアログが出ます。
上位クラスは、上記で選択した、作ろうとするコンポーネントのベースとなるクラスです。
クラス名は、作ろうとするコンポーネントのクラス名です。
パレットページ名は、作ろうとするコンポーネントを格納するコンポーネントパレットのページを指定します。新しいページを作成して格納するには、新しいページの名前を入力します。
ユニットファイル名は、作ろうとするコンポーネントのソースファイル名です。
上記の各項目を入力してOkボタンを押すと、コンポーネント本体のソースファイルのテンプレートが作成され、エディタに表示されます。
コンポーネント本体の作成.
コンポーネント本体の作成については、C++Builderのヘルプの「カスタムコンポーネントの作成」のとおりに順番に行っていけば、作成することが出来ます。といっても、このヘルプでは全体像がつかみにくく、何を説明されているのかわかりにくいのが欠点です。
コンポーネント本体は、基本的には通常の派生クラスと同じですが、いくつか追加でやるべきことがあります。
プロパティ.
プロパティについては、説明が長いので別ページで。
C++Builderのコンポーネントの特徴でもあり、各コンポーネントの特徴が最も出る部分の1つです。
メソッドの追加.
メソッドについては通常のクラスのメソッドと変わりありません。
メソッドはオブジェクトインスペクタで扱わないので、公開するメソッドは__published部ではなくpublic部で定義します。
継承イベントの公開.
イベントについてはプロパティと似ています。上位クラスが提供しているイベントをそのままコンポーネントのユーザに公開することも出来ます。単に派生クラスを作っただけでは上位クラスのイベントは公開されず、コンポーネントのユーザは使用できない点も、プロパティと同じです。上位クラスから継承したイベントを公開したい場合、__published部で再宣言する必要があります。イベントハンドラはオブジェクトインスペクタで指定出来るようにするために、public部で再宣言すべきではありません。
プロパティと同じように、継承イベントを公開するには以下のようにします。単に__propertyキーワードに続けて公開したいイベントのイベント名を記述するだけです。
__property OnClick;
イベントの追加.
残念ながら、上位クラスが提供するものではない、独自のイベントを追加したことはないので、説明できることがありません。
おそらくプロパティと同じようにして、新しいイベントを追加できるものと思います。
注意すべきは、空のイベントハンドラも有効であるということです。イベントハンドラが未指定(NULL)の場合は、イベントハンドラをコールしないようにコーディングする必要があります。
テスト用アプリケーションの作成.
アプリケーションのユニット作成.
コンポーネント本体だけでは動作の確認ができないので、プロジェクト全体としてはコンポーネントを利用するアプリケーションという形で作ります。コンポーネントの動作確認ができるようなテスト用のアプリケーションにするのがいいと思います。
プロジェクト作成直後にはコンポーネント本体のソースファイルしかないので、新しいフォームを作成します。そしてプロジェクトオプションのフォームタブで新しく作ったフォームをメインフォームに指定します。
このようにして作ったプロジェクト内部の各ユニットの位置づけは、プロジェクト本体はコンポーネントのテスト用のアプリケーションのプロジェクト、本節で作成したユニットファイルはコンポーネントのテスト用アプリケーション、コンポーネントのユニット作成で作ったユニットファイルはコンポーネント本体になります。
コンポーネントを作るには他にリソースファイルとかも必要になりますが、ファイルはすべて同じフォルダに入れておきます。
コンポーネントの生成・破棄.
作成したアプリケーションはコンポーネントのテスト用ですから、コンポーネントを生成しなければなりません。コンポーネントパレットから選択して配置したコンポーネントなら、自動的にコンポーネント生成のコードが埋め込まれますが、作成中のコンポーネントはまだそこまで出来ていませんので、プログラマが生成のコードを明示的に記述する必要があります。
コンポーネント生成のために必要な動作を順番に記述すると以下のとおりです。
- コンポーネントのクラスのインスタンスを、newキーワードを使って生成する。場所はメインフォームのコンストラクタでOk。
- Parentプロパティの値を設定する。コンストラクトしたフォームで行えばOk。
- ビジュアルコンポーネントの場合は、フォーム内での位置(Left, Topプロパティ)を指定する。
コンポーネントパレットから配置したコンポーネントは、フォームファイルの読み込み時に上記の処理が行われるので、プログラマが明示的に記述することはありません。しかしまだ説明した範囲ではフォームファイルへの保存に対応していないので、プログラマが明示的に記述する必要があります。
PagePanelの例だと、以下のようになります。
PagePanel1 = new TPagePanel(this); PagePanel1->Parent = this; PagePanel1->Left = 320; PagePanel1->Top = 8;
当然、生成したコンポーネントのインスタンスの破棄も、明示的に記述することになります。
コンポーネントのテストのコード.
あとはコンポーネントの各プロパティ・メソッド・イベントの動作確認のコードを記述するだけです。どのようなものが必要かはコンポーネントの機能により異なります。
注意事項.
テスト用のアプリケーションを作るときに注意事項がいくつか。
- アイコンなどのリソースを格納するのは、コンポーネント(への変換後)の場合はDelphiコンポーネントリソースファイルだが、コンポーネントへの変換前はただのユニットでしかないのでリソースファイル(*.res)に格納する必要がある。つまりテスト用アプリケーションではリソースを、リソースファイルとDelphiコンポーネントリソースファイルの両方に格納する必要がある。
コンポーネントへ変換.
コンポーネントへ変換.
ここまで作ってきたものはアプリケーションの1ユニットでしかなく、コンポーネントの原型となるものです。これをコンポーネントに変換する手順については、長いので別ページで説明します。
読んでいただければわかりますが、やるべきことも多いうえ、難易度も高い作業です。ただコンポーネントの仕様によっては、必要ない部分もあります。
コンポーネントでデバッグ.
この段階でテスト用アプリケーションは、コンポーネントがまだ単なるユニットの状態でのテスト用です。これを、コンポーネントに変換した状態でテストできるように修正しなければ、コンポーネントのテストが出来ません。
まずはコンポーネントパレットからコンポーネントをテスト用アプリケーションのフォームに配置してください。コンポーネントへの変換が出来ていれば、これだけでコンポーネントの生成・破棄と、フォームファイルへの保存・復帰が出来るはずです。コンポーネントの生成・破棄を明示的に行っていたコードは必要なくなるので、コメントアウトします。
オブジェクトインスペクタから各プロパティ・イベントを設定し、それらがフォームファイルに保存されることを確認します。一度フォームを保存して閉じ、再度開いて値が復元されていることを確認します。読み込み後の初期化を明示的に行っている場合は、フォームを開いたときに初期化が期待どおりの結果になっていることを確認する必要もあります。
また、プロパティのデフォルト値を指定して、プロパティ値を選択的にフォームファイルに記録するようにしている場合は、フォームファイルを覗いて、プロパティ値がデフォルト値の場合にのみ記録されることを確認する必要もあります。
カスタムプロパティエディタ・カスタムコンポーネントエディタの作成
カスタムプロパティエディタの作成.
それ自身がクラスであるプロパティ(サブコンポーネント)を直接編集可能にするためには、カスタムプロパティエディタも作成する必要があります。他のコンポーネントによってすでにプロパティエディタが用意されていれば、それを利用することも出来ます。
カスタムコンポーネントエディタの作成.
フォームエディタに配置したコンポーネントを右クリックしたときに表示されるコンテキストメニューや、コンポーネントをダブルクリックしたときの動作を変更したい場合はカスタムコンポーネントエディタを作成する必要があります。
Copyright 2005-2016, yosshie.