来自Resources的资源通过ResourceStream返回nil

时间:2016-04-27 12:00:54

标签: delphi resources pascal

我有一个从资源流返回TPicture对象的函数,它从资源文件中加载PNGImage。

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;

你能告诉我代码有什么问题吗? 图像对象总是 nil ,我在网上搜索答案,或者从资源中将图片加载到TPicture的任何其他方式,但没有找到有帮助的答案。

1 个答案:

答案 0 :(得分: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;