2016-03-21 51 views
3

您好我有一个程序,当加载一个按钮时,在应用程序本身(在这里是一个图像)手动创建一个资源,然后读取资源以显示在timage.El问题是它似乎创建的资源很好,但是当我想要加载资源时说,当你正在寻找时它找不到它。在Delphi中创建和加载资源

代码。

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; 

我解决这个问题吗?

回答

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; 
+0

谢谢雷米,最后一个问题,当我用我的初始代码没有指定一个不同的exe,我的函数损坏了exe,因为他花了那个?因为我有七个64位?一个问题,为什么睡眠(3000); – FF2

+0

; ?谢谢。 – Passella