Foundation > 動的モジュール > 例:動的アクセス
 
例:動的アクセス
この例では、グラフィック・クラスを動作中のアプリケーショから動的にアクセスできるようにします。
IlvFilledRectangle から派生した CrossedRectangle クラスがあり、中に十字が描かれている輪郭付き矩形として表示されていると想定します。例は、次の手順で作成します。
*サンプル・モジュール定義ファイルを書く
*新しいクラスの実装
*例の読み込みと登録
*マクロの登録
*サンプル・クラスを動的モジュールに追加する
サンプル・モジュール定義ファイルを書く
まず、データ・ファイルがクラスの名前を参照したときに、Rogue Wave Views がこのクラスのコードを正しく読み込んでおり、対応するモジュールが明示的に読み込まれることを確認する必要があります。
これを行うには、モジュール定義ファイルを作成します。この例では 1 クラスしか使用しないため、非常に簡単になっています。
以下は、このモジュールの適切なモジュール定義ファイルの内容です。ここではクラスが 1 つしかないため、定義ファイルは次のようになります。クラスのルート・ベース・クラスは IlvGraphic です。
<?xml version = "1.0"?>
<module name="correct" version="1.0">
<class name = "CrossedRectangle" rootClass = "IlvGraphic"/>
</module>
このモジュール定義ファイルには、他の多数のクラスを追加することもできます。IlvGraphic から継承していないクラスでも使用できます。同じモジュールにクラスをインクリメンタルに追加できます。
新しいクラスの実装
モジュール定義ファイルを作成したら、この新しいクラスを実装するための作業を行います。この手順は非常に簡単です。
*中に十字が描かれた塗りつぶし矩形を作成します。
*この新しいクラスが永続的であることを確認します。
*このクラスを動的モジュールに追加します。
最初の 2 手順は既に馴染み深いものかもしれませんが、下記に対応するコードを示します。最後の部分はもっとも難しい箇所です。クラスを正しく登録するためにどのような操作を行うか確認しなければなりません。 残念ながら、IlvRegisterClass マクロは、少なくとも移植可能な方法では、動的読み込みに使用できません。 Rogue Wave Views では、この問題を解決するために、既に使い慣れているマクロに類似したマクロを数種類用意しています。これについては、CrossedRectangle クラスのコードを示した後に説明します。コードは次のとおりです。
#include <ilviews/graphics/rectangl.h>
class CrossedRectangle
: public IlvFilledRectangle {
public:
CrossedRectangle(IlvDisplay* display,
const IlvRect& size, IlvPalette* pal=0)
: IlvFilledRectangle(display, size, pal)
{}
virtual void draw(IlvPort* dst, const IlvTransformer* t = 0,
const IlvRegion* clip = 0) const;
DeclareTypeInfoRO();
DeclareIOConstructors(CrossedRectangle);
};
 
// Copy constructor
CrossedRectangle::CrossedRectangle(const CrossedRectangle& source)
: IlvFilledRectangle(source)
{}
// Read constructor
CrossedRectangle::CrossedRectangle(IlvInputFile& is,
IlvPalette* pal)
: IlvFilledRectangle(is, pal)
{}
void
CrossedRectangle::draw(IlvPort* dst, const IlvTransformer* t,
const IlvRegion* clip) const
{
if (clip)
_palette->setClip(clip);
IlvRect r = _drawrect;
if (t)
t->apply(r);
dst->drawRectangle(_palette, r);
dst->drawLine(_palette, r.upperLeft(), r.lowerRight());
dst->drawLine(_palette, r.upperRight(), r.lowerLeft());
if (clip)
_palette->setClip();
}
IlvPredefinedIOMembers(CrossedRectangle)
draw は、わかりやすいメソッドです。
このクラスには、必要に応じてコピー・コンストラクターおよび永続性に関連するメソッドが備わっていることが分かります。(ここでは保存する情報がないため、write メソッドが備わっていません。このため、クラス宣言に DeclareTypeInfoRO マクロを使用しています)。
新しいクラスを実装する 3 項目のうち 2 つについて既に説明しました。
このクラスを Rogue Wave Views の永続性メカニズムで登録するには、通常は一般的なステートメントを使用します。
IlvRegisterClass(CrossedRectangle, IlvFilledRectangle);
これは、関数の本文外に表示されます。
アプリケーションがそのコードにリンクしている場合、CrossedRectangle クラスのインスタンスの操作、保存、読み込みができます。ただし、CrossedRectangle クラスを必ず既存アプリケーションに認識させてください。既存アプリケーションは開発時にこのクラスを認識していないため、このクラスが定義されるアプリケーションが生成するデータ・ファイルを読み込むようになっています。これを行うには、このクラスを動的モジュールに接続する必要があります。その結果、以前のマクロをこの目的に使用することができなくなります。
例の読み込みと登録
ここでは、モジュールが読み込まれるとどうなるか、登録とは実際に何を行うのかを理解します。
*モジュールの読み込み時に、そのコンストラクターが呼び出されます。
*登録とは、クラスレベルのアトリビュートを格納するクラス・レベルの変数宣言とこれらの変数を実際に更新する関数の呼び出しです。
Rogue Wave Views は動的モジュール機能により、IlvRegisterXXXClass マクロの代替を用意しています。これは多くの場所で使用されます (IlvGraphic および IlvNamedProperty サブクラスなど)。このマクロ一式は、登録の宣言と定義を切り離します。
登録の宣言の部分に使用されるマクロ名は、IlvRegisterIlvPreRegister となっていることを除き、IlvRegisterXXXClass に類似しています。IlvRegisterXXXClass の 2 つ目のパラメーターが省略されています。このマクロ呼び出しは、関数の本文外に記述されなければなりません (これはクラス・レベルの変数のみを宣言します)。
登録の定義の部分に使用されるマクロ名は、IlvRegisterIlvPostRegister となっていることを除き、IlvRegisterXXXClass に類似しています。IlvRegisterXXXClass の 2 つ目のパラメーターはそのままです。したがって、マクロ呼び出しは、呼び出されて実際に登録を正しく行う関数の本文内に記述されなければなりません (新しいクラスを登録するコードは呼び出しません)。
この例では、グラフィック・クラスを登録するために、IlvPreRegisterClass マクロ (関数の本文外) および IlvPostRegisterClass マクロ (関数の本文内) の両方を使用する必要があります。
マクロの登録
以下は、永続的な Rogue Wave Views クラスのほとんどの登録に使用する必要があるマクロのリストです (c は登録されているクラス名を、s は親クラス名を示しま
す)。
動的モジュールでのマクロ登録 
クラス名
静的な登録マクロ
動的モジュールでのマクロ登録
IlvRegisterClass(c, s);
IlvPreRegisterClass(c);
IlvPostRegisterClass(c, s);
IlvRegisterPropertyClass(c, s);
IlvPreRegisterPropertyClass(c);
IlvPostRegisterPropertyClass(c, s);
IlvRegisterViewClass(c, s);
IlvPreRegisterViewClass(c);
IlvPostRegisterViewClass(c, s);
IlvRegisterGadgetItemClass(c, s);
IlvPreRegisterGadgetItemClass(c);
IlvPostRegisterGadgetItemClass(c, s);
ガジェットの詳細については、Gadgets マニュアルを参照してください。
IlvRegisterNotebookPageClass(c, s);
IlvPreRegisterNotebookPageClass(c);
IlvPostRegisterNotebookPageClass(c, s);
IlvRegisterSmartSetClass(c, s);
IlvPreRegisterSmartSetClass(c);
IlvPostRegisterSmartSetClass(c, s);
IlvRegisterGroupClass(c, s);
IlvPreRegisterGroupClass(c);
IlvPostRegisterGroupClass(c, s);
IlvRegisterGroupNodeClass(c, s);
IlvPreRegisterGroupNodeClass(c);
IlvPostRegisterGroupNodeClass(c, s);
IlvRegisterUserAccessorClass(c, s);
IlvPreRegisterUserAccessorClass(c);
IlvPostRegisterUserAccessorClass(c, s);
ここでは IlvGraphic のサブクラスを使用しているため、モジュールのソース・コード作成に必要なのは IlvPreRegisterClass マクロおよび IlvPostRegisterClass マクロのみです。
サンプル・クラスを動的モジュールに追加する
以下は、最終ソース・コードを Rogue Wave Views 動的モジュールにコンパイルできるように、CrossedRectangle クラスの定義に追加するコードです。
#include <ilviews/base/modules.h>
 
IlvPreRegisterClass(CrossedRectangle);
 
class MyModule
: public IlvModule
{
public:
MyModule(void*)
{
IlvPostRegisterClass(CrossedRectangle, IlvFilledRectangle);
}
};
 
ILVINITIALIZEMODULE(MyModule);
このコードをプレコンパイラー・ブロックである #if defined()/#else/#endif に追加することができます。この場合、通常の
IlvRegisterClass(CrossedRectangle, IlvFilledRectangle);
if#else に埋め込みます。これにより、コードを通常の静的オブジェクト・ファイルとして、または動的モジュールとしてコンパイルできます。
#if defined(MAKE_A_MODULE)
#include <ilviews/base/modules.h>
 
IlvPreRegisterClass(CrossedRectangle);
 
class MyModule
: public IlvModule
{
public:
MyModule(void*)
{
IlvPostRegisterClass(CrossedRectangle, IlvFilledRectangle);
}
};
 
ILVINITIALIZEMODULE(MyModule);
#else /* DONT_MAKE_A_MODULE */
IlvRegisterClass(CrossedRectangle, IlvFilledRectangle);
#endif /* DONT_MAKE_A_MODULE */

Version 6.0
Copyright © 2015, Rogue Wave Software, Inc. All Rights Reserved.