2016-03-21 2 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, тогда вы можете загружать DLL динамически через LoadLibrary(), когда вам нужно загрузить свои ресурсы и выгрузить его через 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

спасибо Remy, Последний вопрос, когда я использовал свой первоначальный код без указания другого exe, моя функция исказила exe, потому что он потратил это? потому что у меня семь 64-битных? – FF2

+0

один вопрос, почему Sleep (3000); ? Благодарю. – Passella

Смежные вопросы