我有一个从资源流返回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的任何其他方式,但没有找到有帮助的答案。
答案 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;