私は次の子孫の例を持っていますTBitmap
:
TMyBitmap = class(TBitmap)
public
constructor Create; override;
end;
constructor TMyBitmap.Create;
begin
inherited;
Beep;
end;
実行時に、これらのTMyBitmap
オブジェクトの1つを作成し、それに画像をロードしてTImage
、フォーム上のに配置します。
procedure TForm1.Button1Click(Sender: TObject);
var
g1: TGraphic;
begin
g1 := TMyBitmap.Create;
g1.LoadFromFile('C:\...\example.bmp');
Image1.Picture.Graphic := g1;
end;
内部では、新しいグラフィックを作成し、新しく作成されたクローンTPicture.SetGraphic
を呼び出すことで、グラフィックのコピーを作成していることがわかります。.Assign
procedure TPicture.SetGraphic(Value: TGraphic);
var
NewGraphic: TGraphic;
begin
...
NewGraphic := TGraphicClass(Value.ClassType).Create;
NewGraphic.Assign(Value);
...
end;
新しいグラフィッククラスが構築される行:
NewGraphic := TGraphicClass(Value.ClassType).Create;
コンストラクターを正しく呼び出し、すべてが順調です。
私は似たようなことをしたい、私はクローンを作りたいTGraphic
:
procedure TForm1.Button1Click(Sender: TObject);
var
g1: TGraphic;
g2: TGraphic;
begin
g1 := TMyBitmap.Create;
g1.LoadFromFile('C:\...\example.bmp');
//Image1.Picture.Graphic := g1;
g2 := TGraphicClass(g1.ClassType).Create;
end;
これが私のコンストラクターを呼び出すことも、コンストラクターを呼び出すこともないことを除いてTBitmap
。コンストラクターを呼び出すだけTObject
です。建設後:
g2.ClassName: 'TMyBitmap'
g2.ClassType: TMyBitmap
タイプは正しいですが、コンストラクターを呼び出しませんが、他の場所で同じコードを呼び出します。
なんで?
この架空の考案された例でも、のコンストラクターTBitmap
が呼び出されていないため、まだ問題があります。内部状態変数が有効な値に初期化されていません:
constructor TBitmap.Create;
begin
inherited Create;
FTransparentColor := clDefault;
FImage := TBitmapImage.Create;
FImage.Reference;
if DDBsOnly then HandleType := bmDDB;
end;
TPictureのバージョン:
NewGraphic := TGraphicClass(Value.ClassType).Create;
次のように逆コンパイルします。
mov eax,[ebp-$08]
call TObject.ClassType
mov dl,$01
call dword ptr [eax+$0c]
mov [ebp-$0c],eax
私のバージョン:
g2 := TGraphicClass(g1.ClassType).Create;
次のように逆コンパイルします。
mov eax,ebx
call TObject.ClassType
mov dl,$01
call TObject.Create
mov ebx,eax
アップデートワン
「クローン作成」を別の機能にプッシュする:
function CloneGraphic(Value: TGraphic): TGraphic;
var
NewGraphic: TGraphic;
begin
NewGraphic := TGraphicClass(Value.ClassType).Create;
Result := NewGraphic;
end;
助けにはなりません。
アップデート2
明らかに、私は明確なコードの明確なスクリーンショットを明確に提供しています。これは、明確なコードが明確にすべて存在することを明確に示しています。明らかに:
アップデート3
OutputDebugString
sを使用した明確なバージョンは次のとおりです。
{ TMyGraphic }
constructor TMyBitmap.Create;
begin
inherited Create;
OutputDebugStringA('Inside TMyBitmap.Create');
end;
function CloneGraphic(Value: TGraphic): TGraphic;
var
NewGraphic: TGraphic;
begin
NewGraphic := TGraphicClass(Value.ClassType).Create;
Result := NewGraphic;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
g1: TGraphic;
g2: TGraphic;
begin
OutputDebugString('Creating g1');
g1 := TMyBitmap.Create;
g1.LoadFromFile('C:\Archive\-=Images=-\ChessvDanCheckmateIn38.bmp');
OutputDebugString(PChar('g1.ClassName: '+g1.ClassName));
OutputDebugStringA('Assigning g1 to Image.Picture.Graphic');
Image1.Picture.Graphic := g1;
OutputDebugString('Creating g2');
g2 := Graphics.TGraphicClass(g1.ClassType).Create;
OutputDebugString(PChar('g2.ClassName: '+g2.ClassName));
OutputDebugString(PChar('Cloning g1 into g2'));
g2 := CloneGraphic(g1);
OutputDebugString(PChar('g2.ClassName: '+g2.ClassName));
end;
そして生の結果:
ODS: Creating g1 Process Project2.exe ($1138)
ODS: Inside TMyBitmap.Create Process Project2.exe ($1138)
ODS: g1.ClassName: TMyBitmap Process Project2.exe ($1138)
ODS: Assigning g1 to Image.Picture.Graphic Process Project2.exe ($1138)
ODS: Inside TMyBitmap.Create Process Project2.exe ($1138)
ODS: Creating g2 Process Project2.exe ($1138)
ODS: g2.ClassName: TMyBitmap Process Project2.exe ($1138)
ODS: Cloning g1 into g2 Process Project2.exe ($1138)
ODS: g2.ClassName: TMyBitmap Process Project2.exe ($1138)
ODS: g1.ClassName: TMyBitmap Process Project2.exe ($1138)
そしてフォーマットされた結果:
Creating g1
Inside TMyBitmap.Create
g1.ClassName: TMyBitmap
Assigning g1 to Image.Picture.Graphic
Inside TMyBitmap.Create
Creating g2
g2.ClassName: TMyBitmap
Cloning g1 into g2
g2.ClassName: TMyBitmap
g1.ClassName: TMyBitmap
アップデート4
私は私ができるすべてのコンパイラオプションをオフにしてみました:
注:オフにしないでくださいExtended syntax
。Result
これがないと、関数のを割り当てることができません(宣言されていない識別子の結果)。
アップデートファイブ
@Davidの提案に従って、他のいくつかのマシン(すべてDelphi 5)でコードをコンパイルしてみました。
- Ian Boyd(me):失敗(Windows 7 64ビット)
- デール:失敗(Windows 7 64ビット)
- デイブ:失敗(Windows 7 64ビット)
- クリス:失敗(Windows 7 64ビット)
- ジェイミー:失敗(Windows 7 64ビット)
- ジェイ:失敗(Windows XP 32ビット)
- カスタマービルドサーバー:失敗(Windows 7 32ビット)