Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Add resource [D6, D7, Win2k, WinXP]


kernel ©   (2006-05-01 08:14:00) 

Проблема вот в чем. Чтобы добавить из своей программы к другому EXE файлу ресурс (в данном случае обычный файл) я использую функцию:

function AddResource(FileName, ResName: string; Buf: pointer; Size: integer): integer;
var
 Hnd: THandle;
begin
 Hnd := BeginUpdateResource(PChar(FileName), false);
 if Hnd=0 then begin
   result := GetLastError; Exit;
 end;
 if UpdateResource(Hnd, RT_RCDATA, PChar(ResName), 1049, Buf, Size) then
   result := 0
 else result := GetLastError;
 EndUpdateResource(Hnd, (result<>0));
end;

function AddFileToExe(ExeName, FileName, ResName: string): boolean;
var
 fs: TFileStream;
 b:  pointer;
begin
 try
   fs := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
   GetMem(b, Get fs.Size);
   fs.Read(b, fs.Size);
   AddResource(ExeName, ResName, b, fs.Size);
   fs.Free;
   FreeMem(b);
 except
   result := false;
 end;
end;

begin
AddFileToExe([ExeName], [FileName], [ResName]);
end.


Всё нормально, но только почему то если я пытаюсь добавить файл размером, например, 110 байт, программа слетает (и каждый раз выводится разная ошибка).


kernel   (2006-05-01 17:56:00) [1]

Спасибо, begin...end. Все отлично работает. Только не могу понять, почему-то раньше пробовал MemoryStream - не получалось. А сейчас попробывал - получилось. :)


begin...end   (2006-05-01 08:34:00) [2]

> kernel ©   (01.05.06 08:14)

> и каждый раз выводится разная ошибка

...а какая ошибка -- тайна сия велика есть. Догадайся, мол, сама.

Но одна из возможных причин ошибки лежит на поверхности:

> fs.Read(b, fs.Size);

В качестве первого параметра Read Вы указали АДРЕС буфера, а нужно указать САМ буфер. Т.е. нужно так:

fs.Read(b ^, fs.Size).

Но я бы вместо TFileStream использовал TMemoryStream:

function AddFileToExe(ExeName, FileName, ResName: string): Boolean;
var
 MS: TMemoryStream;
begin
 Result := False;
 MS := TMemoryStream.Create;
 try
   MS.LoadFromFile(FileName);
   AddResource(ExeName, ResName, MS.Memory, MS.Size);
   Result := True
 finally
   MS.Free
 end
end.

Как видите, в этом случае нет необходимости самостоятельно выделять/освобождать память -- об этом позаботится MemoryStream.


Наверх

Титульная страница Поиск, карта сайта Написать письмо