2016-04-27 23 views
-1

リソースファイルからPNGImageをロードするリソースストリームからTPictureオブジェクトを返す関数があります。リソースからResourceStream経由で画像を返す

function getImage(AName : string; lvl : integer): TPicture; 
var Loader : TResourceStream; 
    image : TPngImage; 
begin 
    Image := TPngImage.Create; 
    try begin 
     Loader := TResourceStream.Create(hInstance, AName+'_l'+IntToStr(lvl) , RT_RCDATA); 
     Loader.Position := 0; 
     Image.LoadFromStream(Loader); 
     result.Graphic := Image; 
     end 
    finally 
    Image.Free; 
    Loader.Free; 
    end; 
end; 

コードの問題点を教えてください。 の画像のオブジェクトは常にで、と答えています。答えは、Webから検索して、リソースからTPictureに画像を読み込む方法ですが、役に立たない回答は見つかりませんでした。

+0

このコードは完全に壊れています。結果は決して初期化されません。 Loaderが初期化されているかどうかに関係なく、Loaderを解放するので、try/finallyは間違っています。 Pointlessはストリームの位置をコード内のその時点にあるので0に設定します。 'Result'が' nil'ならランタイムAVエラーが発生するので、関数は必ず 'nil'を返しません。私は質問を閉じるために投票しています –

+0

@lurkerはそれが不可能ではないでしょう –

+0

それは不可能です。それはnilではないか、例外が発生したかのいずれかです。 –

答えて

2

コメントに記載されているとおり、コードはかなり壊れています。それはより多くの代わりにこのようになります。

function getImage(AName : string; lvl : integer): TPicture; 
var 
    Loader : TResourceStream; 
    image : TPngImage; 
begin 
    Result := nil; 
    Image := TPngImage.Create; 
    try 
    Loader := TResourceStream.Create(hInstance, AName+'_l'+IntToStr(lvl), RT_RCDATA); 
    try 
     Image.LoadFromStream(Loader); 
    finally 
     Loader.Free; 
    end; 
    Result := TPicture.Create; 
    try 
     Result.Graphic := Image; 
    except 
     Result.Free; 
     raise; 
    end; 
    finally 
    Image.Free; 
    end; 
end; 

はその後、呼び出し側がこれを行うことができます:

言われていること
var 
    Pic: TPicture; 
begin 
    Pic := getImage(...); 
    try 
    // use Pic as needed... 
    finally 
    Pic.Free; 
    end; 
end; 

が、一般的に関数の結果として新しいオブジェクトを返すために良いデザインの選択ではありません。呼び出し側は、オブジェクトを作成し、中に充填する関数に渡し、オブジェクトがどこから来るか、発信者が選択できるような方法は、(例えば、TImage.Pictureプロパティを使用)する必要があります

procedure getImage(AName : string; lvl : integer; APicture: TPicture); 
var 
    Loader : TResourceStream; 
    image : TPngImage; 
begin 
    APicture.Assign(nil); 
    Image := TPngImage.Create; 
    try 
    Loader := TResourceStream.Create(hInstance, AName+'_l'+IntToStr(lvl), RT_RCDATA); 
    try 
     Image.LoadFromStream(Loader); 
    finally 
     Loader.Free; 
    end; 
    APicture.Graphic := Image; 
    finally 
    Image.Free; 
    end; 
end; 

その後、発信者が行うことができますこの:

var 
    Pic: TPicture; 
begin 
    Pic := TPicture.Create; 
    try 
    getImage(..., Pic); 
    // use Pic as needed... 
    finally 
    Pic.Free; 
    end; 
end; 

またはこの:

begin 
    getImage(..., Image1.Picture); 
end; 
関連する問題