例えば、以下のような、ファイルの拡張子から画像表示するためのクラス参照型を返す関数を用意します。
function GetGraphicClass(aFile: String): TGraphicClass;
begin
.bmp であれば Result := TBitmap;
.png であれば Result := TGldPng; //Delphian Worldにあるコンポーネント)
〜〜 等
end;
また、以下のような関数があります(エラー処理等は省略)。
procedure TForm1.HogeHoge;
var
grphClass: TGraphicClass;
newGrap: TGraphic;
begin
grphClass := GetGraphicClass(どっかの画像ファイル名);
newGrap := grphClass.Create; //.......(1)
newGrap.LoadFromFile(どっかの画像ファイル名);
Image1.Graphic.Assign(newGrap)
end;
これは、拡張子を判定し、適切な画像クラスでファイルを読み込み、
Formに貼り付けたImage1に表示するプログラム(と思ってください)。
ここで、プロジェクトのオプションで、デバック版DCUを使うようにし実行します。
(1)でブレークポイントを設定し、ここからF7でトレース実行を行います。
そうすると、bmpであれば、TBitmap.Createを実行する・・・と思っていたのですが、いきなりTObject.Createまで飛んでしまいます。
TBitmap.Createの先頭行にブレークポイントをつけても、全く止まりません。
逆に、上記例を変更し以下のようにクラス別に、明示的にクリエイトすると、正しくTbitmap.Createが実行されます(当然だわな)。...(2)
if grphClass = TBitmap then begin
newGrap := TBitmap.Create;
end
else 〜〜
「class of クラス名」って、そんなんか!?と、自分で定義したクラス型の実装部で、(1)の例のように、クラス参照型変数からのCreateをステップ実行しましたが、正しく実行されています。
もちろん、{$D-}は、はずしているので、止まらないことはありません。
(2)のように書いておけば、正しく動作するので。
TGraphicClass が、思ったように動かないのって、な〜ぜ〜!?
grphClass: TGraphicClass;
となっているからでは?
grphClass.Createは TGraphicClassの Createを呼び出すだけかと・・・
Graphics.pasに宣言してあります。
TGraphicClass = class of TGraphic;
したがって、TGraphicClassは、フツーのクラスじゃありません。
だから、
grphClass := TBitmap;
xxx := grphClass.Create;
と書けば、TBitmapのインスタンスがクリエイトできると考えていたのですが(・_・")?
いい加減なレスを付けてしまいましたね。
ごめんなさい。
確認してみましたが
...
var
grphClass: TGraphicClass;
newGrap: TGraphic;
begin
grphClass := TBitmap;
newGrap := grphClass.Create;
...
で ちゃんとTBitmapのCreateは呼び出されていますけど。
TGraphicClassはクラス参照型ですね。
こちらの環境では、正しくTBitmap.Createを呼んでいます。
# Delphi7 Pro, WindowsXP Pro
新規にプロジェクトをおこして、最小のコードで試しても起きます?
kkkさん、にしのさん、実験ありがとうございます。
これだけで再現。
WindowsXP SP1 Pro + D5up1
unit Unit1;
interface
uses
Windows, Classes, Controls, ExtCtrls, Forms, Graphics;
type
TForm1 = class(TForm)
Image1: TImage;
procedure FormShow(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormShow(Sender: TObject);
var
grphClass :TGraphicClass;
newGraphic :TGraphic;
begin
grphClass := TBitmap;
newGraphic := grphClass.Create; //(1)
newGraphic.LoadFromFile('C:\Graphic\色塗り初期色設定256.bmp');
Image1.Picture.Assign(newGraphic);
newGraphic.Free;
end;
end.
(1)で止めてトレースすると、(2)まで飛びます。
constructor TObject.Create;
begin //(2)
end;
クラス参照型を返さず、対応したインスタンスを返せばいいのかもしれませんが、仕様上、そういうわけにもいかんのです。
D5が悪いのか?開発環境が悪いのか?
念のため上記のソースそのままチェックしてみました。
やはり正常に TBitmap.Createに飛んでいます。
WindowsXP Pro SP2,Delphi7Pro upd1
比較的クリーン環境?で実行したところ、見事に同じようにスルーされてしまいました。
インストしたてのD5環境があれば、それでもテストしたいな。
そこで再現するなら、少なくともD5のせい。
やっかいな話だ。
ツイート | ![]() |