class of TGraphic(TGraphicClass)


とおりすがらない  2005-05-27 20:02:54  No: 15120

例えば、以下のような、ファイルの拡張子から画像表示するためのクラス参照型を返す関数を用意します。

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 が、思ったように動かないのって、な〜ぜ〜!?


kkk  2005-05-27 20:28:31  No: 15121

grphClass: TGraphicClass;
となっているからでは?
grphClass.Createは TGraphicClassの Createを呼び出すだけかと・・・


とおりすがらない  2005-05-27 20:51:58  No: 15122

Graphics.pasに宣言してあります。
TGraphicClass = class of TGraphic;

したがって、TGraphicClassは、フツーのクラスじゃありません。

だから、
  grphClass := TBitmap;
  xxx := grphClass.Create;
と書けば、TBitmapのインスタンスがクリエイトできると考えていたのですが(・_・")?


kkk  2005-05-27 21:00:36  No: 15123

いい加減なレスを付けてしまいましたね。
ごめんなさい。


kkk  2005-05-27 21:13:02  No: 15124

確認してみましたが
...
var
   grphClass: TGraphicClass;
  newGrap: TGraphic;
begin
  grphClass := TBitmap;
  newGrap := grphClass.Create;
...
で ちゃんとTBitmapのCreateは呼び出されていますけど。


にしの  2005-05-27 21:13:10  No: 15125

TGraphicClassはクラス参照型ですね。

こちらの環境では、正しくTBitmap.Createを呼んでいます。
# Delphi7 Pro, WindowsXP Pro
新規にプロジェクトをおこして、最小のコードで試しても起きます?


とおりすがらない  2005-05-27 22:36:33  No: 15126

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が悪いのか?開発環境が悪いのか?


kkk  2005-05-27 23:06:49  No: 15127

念のため上記のソースそのままチェックしてみました。
やはり正常に TBitmap.Createに飛んでいます。
WindowsXP Pro SP2,Delphi7Pro upd1


とおりすがらない  2005-05-27 23:20:51  No: 15128

比較的クリーン環境?で実行したところ、見事に同じようにスルーされてしまいました。

インストしたてのD5環境があれば、それでもテストしたいな。
そこで再現するなら、少なくともD5のせい。

やっかいな話だ。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加