嗨我有一个程序,当一个按钮加载时,在应用程序本身手动创建一个资源(在这种情况下是一个图像),然后读取资源显示在一个timage.El问题是它似乎创建了资源很好,但是当我想要加载时,资源说它在你找的时候找不到它。
代码。
procedure StringtoRes(const FileName: string; Inputstream: TMemoryStream);
var
hUpdate: THandle;
begin
hUpdate := BeginUpdateResource(PChar(FileName), True);
try
UpdateResource(hUpdate, RT_RCDATA, 'ID', LANG_NEUTRAL, Inputstream.Memory,
Inputstream.Size);
finally
EndUpdateResource(hUpdate, False);
end;
end;
procedure TForm1.btnTestClick(Sender: TObject);
var
MemStr: TMemoryStream;
FileName: string;
var
RStream: TResourceStream;
JPEGImage: TJPEGImage;
begin
FileName := 'c:/test/test.jpg';
MemStr := TMemoryStream.Create;
MemStr.LoadFromFile(FileName);
MemStr.Seek(0, soFromBeginning);
StringtoRes(paramstr(0), MemStr);
MemStr.Free;
Sleep(3000);
RStream := TResourceStream.Create(HInstance, 'ID', RT_RCDATA);
JPEGImage := TJPEGImage.Create;
JPEGImage.LoadFromStream(RStream);
Image1.Picture.Graphic := JPEGImage;
JPEGImage.Free;
RStream.Free;
end;
我解决了这个问题?
答案 0 :(得分:4)
通常,正在运行的进程无法更新自己的资源,因为其可执行文件已锁定且无法写入。要执行您尝试的操作,您应该将资源移动到单独的DLL,然后您可以在需要加载资源时通过LoadLibrary()
动态加载DLL,并在需要时通过FreeLibrary()
卸载它更新资源。
var
hResLib: THandle = 0;
procedure TForm1.btnTestClick(Sender: TObject);
var
ResFileName: string;
MemStr: TMemoryStream;
RStream: TResourceStream;
JPEGImage: TJPEGImage;
begin
ResFileName := ExtractFilePath(ParamStr(0)) + 'myres.dll';
if hResLib <> 0 then
begin
FreeLibrary(hResLib);
hResLib := 0;
end;
MemStr := TMemoryStream.Create;
try
MemStr.LoadFromFile('c:/test/test.jpg');
MemStr.Position := 0;
StringtoRes(ResFileName, MemStr);
finally
MemStr.Free;
end;
Sleep(3000);
hResLib := LoadLibrary(ResFileName);
Win32Check(hResLib <> 0);
RStream := TResourceStream.Create(hResLib, 'ID', RT_RCDATA);
try
JPEGImage := TJPEGImage.Create;
try
JPEGImage.LoadFromStream(RStream);
Image1.Picture.Graphic := JPEGImage;
finally
JPEGImage.Free;
end;
finally
RStream.Free;
end;
end;
另外,在调用BeginUpdateResource()
之前,您没有检查UpdateResource()
的返回值以确保其实际成功。
procedure StringtoRes(const FileName: string; Inputstream: TMemoryStream);
var
hUpdate: THandle;
bDiscard: BOOL;
begin
hUpdate := BeginUpdateResource(PChar(FileName), True);
Win32Check(hUpdate <> 0); // <-- ADD THIS!
bDiscard := True;
try
Win32Check(UpdateResource(hUpdate, RT_RCDATA, 'ID', LANG_NEUTRAL, Inputstream.Memory, Inputstream.Size));
bDiscard := False;
finally
EndUpdateResource(hUpdate, bDiscard);
end;
end;