2016-03-21 91 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