Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 348

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Мой вопрос касается формата res файлов, хочется иметь возможность програмно создавать res файлы из своего приложения, для чего пишу простенькую программу, в которой при нажатии на кнопку из 4 картинок формируется файл ресурсов, для дальнейшей работы с ним.
Поискав в интернете ключ к res формату, удалось найти только это
http://msdn.microsoft.com/en-us/library/ms648007(VS.85).aspx
откуда следует что ресурсы состоят из шапки из 4 полей(размер шапки,размер ресурса,тип ресурса,имя ресурса)
С 1б2б4 параметрами понятно, но вот с 3 както все размыто толи тут тип Cardinal, толи String, по следующей ссылке кажется что это Cardinal
http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx
Но когда начинаешь считывать готовые файлы ресурсов, то размер шапки оказывается почемуто равен 0, а размер самого ресурса равен 32 причем так всегда.
Суть вопроса: помогите разобраться с форматом res файлов

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Приложение:
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. Button1: TButton;
  12. Button2: TButton;
  13. OpenDialog1: TOpenDialog;
  14. Label1: TLabel;
  15. Label2: TLabel;
  16. Label3: TLabel;
  17. Label4: TLabel;
  18. Label5: TLabel;
  19. Label6: TLabel;
  20. Label7: TLabel;
  21. Label8: TLabel;
  22. procedure Button1Click(Sender: TObject);
  23. procedure Button2Click(Sender: TObject);
  24. private
  25. { Private declarations }
  26. public
  27. { Public declarations }
  28. end;
  29.  
  30. Const
  31. RcType: string='RCDATA'; //RT_RCDATA MAKEINTRESOURCE(10)
  32.  
  33.  
  34. var
  35. Form1: TForm1;
  36. MyRes,SrcFile: File of byte;
  37.  
  38. implementation
  39.  
  40. {$R *.dfm}
  41.  
  42.  
  43.  
  44. var
  45. i:integer;
  46. NumRead, NumWritten: Integer;
  47. Buf: array[1..2048] of Byte;
  48. RcHeader,RcSize: Cardinal;
  49. RcName: String;
  50. begin
  51. AssignFile(MyRes,'Resource.res');
  52. Rewrite(MyRes);
  53.  
  54. Begin
  55.  
  56.  
  57. AssignFile(SrcFile,RcName);
  58. Reset(SrcFile);
  59.  
  60.  
  61.  
  62.  
  63. BlockWrite(MyRes, RcHeader, SizeOf(RcHeader), NumWritten);
  64. BlockWrite(MyRes, RcSize, SizeOf(RcSize), NumWritten);
  65. BlockWrite(MyRes, RcType, SizeOf(RcType), NumWritten);
  66. BlockWrite(MyRes, RcName, SizeOf(RcName), NumWritten);
  67.  
  68.  
  69. while Not(EOF(SrcFile)) do
  70. Begin
  71. BlockRead(SrcFile,Buf,SizeOf(Buf),NumRead);
  72. BlockWrite(MyRes,Buf,NumRead,NumWritten);
  73. End;
  74. {repeat
  75. BlockRead(SrcFile, Buf, SizeOf(Buf), NumRead);
  76. BlockWrite(MyRes, Buf, NumRead, NumWritten);
  77. until (NumRead = 0) or (NumWritten <> NumRead);}
  78.  
  79.  
  80. CloseFile(SrcFile);
  81. End;
  82. CloseFile(MyRes);
  83. end;
  84.  
  85.  
  86.  
  87.  
  88. var
  89. NumRead: Integer;
  90. RcHeader,RcSize: Cardinal;
  91. RcName: String;
  92. RcType:String;
  93. begin
  94. if OpenDialog1.Execute=true then
  95. AssignFile(SrcFile,OpenDialog1.FileName);
  96. Reset(SrcFile);
  97. BlockRead(SrcFile,RcHeader,4,NumRead);
  98. BlockRead(SrcFile,RcSize,4,NumRead);
  99. //BlockRead(SrcFile,RcType,SizeOf(RcType),NumRead);
  100. Label5.Caption:=IntToStr(RcHeader);
  101. Label6.Caption:=IntToStr(RcSize);
  102. //Label7.Caption:=IntToStr(RcType);
  103. CloseFile(SrcFile);
  104. end;
  105.  
  106. end.


SOA Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: SOA (статус: Посетитель)
Вопрос отправлен: 20 июня 2010, 15:20
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 16; последнее сообщение — 27 июня 2010, 13:06; участников в обсуждении: 5.
min@y™

min@y™ (статус: Доктор наук), 20 июня 2010, 15:33 [#1]:

Забудь ты про паскалевские функции работы с файлами. Юзай TFileStream.

З.Ы.
BlockWrite(MyRes, RcName, SizeOf(RcName), NumWritten);
Сам-то понял, что написал?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
SOA

SOA (статус: Посетитель), 20 июня 2010, 15:58 [#2]:

Я знаю что работать с TFileStream быстрее, но и у меня тут тоже не потоковое видео, так что не суть;)
min@y™

min@y™ (статус: Доктор наук), 20 июня 2010, 16:03 [#3]:

Да причём тут быстрее? Я имел в виду, что это УДОБНЕЕ!
Так что СУТЬ!
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
bugmenot

bugmenot (статус: 3-ий класс), 20 июня 2010, 16:47 [#4]:

На самом деле без разницы, хотя потоки специально заточены под слабоструктурированные данные.
А про стринг кури тщательнее что такое MAKEINTRESOURCE
виконання програми розпочинається з того самого мiсця, де призупинилося.

SOA

SOA (статус: Посетитель), 20 июня 2010, 17:38 [#5]:

To min@y™: Учту.
To bugmenot: за MAKEINTRESOURCE спасибо, она переводит числовое значение равное тому или иному типу ресурсов в строковое значение в unicode.
Здесь нашел описание всех типов,
http://msdn.microsoft.com/en-us/library/ms648027(VS.85).aspx
оказывается они все типа DWORD, отсюда возникает вопрос как в DWORD поместить значение типа string, потому что там не пишут какую функцию использовать для этого, правда пишут что можно использовать строку типа unicode с нулевым окончанием, либо просто нумеровать ресурс. С нумерованием все понятно, а вот со строкой с нулевым окончание траблы, потому что на то что написано ниже компилятор ругается, а я именно так понимаю понятие строки с нулевым окончанием.
RCNAME:=((IntToStr(i)+'.bmp'),0);
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 20 июня 2010, 18:51 [#6]:

Цитата (SOA):

RCNAME:=((IntToStr(i)+'.bmp'),0);

это что за конструкция? Правильно ругается.
SOA

SOA (статус: Посетитель), 20 июня 2010, 18:53 [#7]:

RCNAME:DWORD
но ms пишут что можно использовать строку unicode, с нулевым окончанием, ее то я и пытаюсь реализовать таким образов ведь как я понимаю это s:='bebrtbr',0;
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 20 июня 2010, 19:51 [#8]:

с каких пор простые скобки стали использоваться в качестве имени функции? Строки с нулевым окончанием понимаете неправильно, почитаете про pchar, например, в хелпе.
SOA

SOA (статус: Посетитель), 20 июня 2010, 20:42 [#9]:

To Мережников Андрей: почитал help, оттуда следует что PChar это указатель на память, где хранится структура типа string, не понимаю причем тут строки с нулевым окончанием?
Выдержки из help:
A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, and not a reference counted copy of the string. For example:

function title(n: Integer): PChar;
var
s: string;
begin
s := Format('title - %d', [n]);
Result := PChar(s); // DON'T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.
SOA

SOA (статус: Посетитель), 20 июня 2010, 21:08 [#10]:

To Мережников Андрей: почитал тут
http://www.hostmake.ru/articles/delphi/356/
теперь все понятно спасибо.
bugmenot

bugmenot (статус: 3-ий класс), 20 июня 2010, 22:02 [#11]:

а там написано где-то "если старшее слово этого PChar`а = 0, то младшее считается целочисленным идентификатором ресурса"
виконання програми розпочинається з того самого мiсця, де призупинилося.

Maksell

Maksell (статус: Посетитель), 21 июня 2010, 21:31 [#12]:

BeginUpdateResorce
Объявление в VB: Declare Function BeginUpdateResource& Lib "kernel32" Alias _"DeginUpdateResourceA" (ByVal pFileName as String, ByVal _bDeleteExistingResources As Long)As Long

Описание: Функция начинает процесс обновления ресурсов в исполняемом файле.

Параметр тип/описание
pFileName String - строка, асоциируемая с атомом (имя атома)
bDeleteExistingResources Long - TRUE (НЕнулевое значение) для удаления всех текущих ресурсов в файле. Если параметр равен FALSE, существующие ресурсы изменяються лишь в том случае, если это указано при вызове UpdateResource.

Возвращаемое значение: Long - манипулятор, используемый функцией UpdateResource при обновлении ресурсов в файле.

Платформа: Windows NT

Комментарии: Ресурсы, хранящиеся в исполняемом файле или DLL, можно объявлять. Для етого следует сначала вызвать функцию BeginUpdateResorce, затем вызвать UpdateResource для каждого обновляемого ресурса и завершить операцию обновления вызовом EndUpdateResorce.


EndUpdateResource
Объявление в VB: Declare Function EndUpdateResource Lib "kernel32" Alias "EndUpdateResourceA" (ByVal hUpdate As Long, ByVal fDiscard As Long) As Long

Описание: Функция завершает операцию обновления ресурсов.

Параметр тип/описание
hUpdate Long - манипулятор, возвращаемый функцией BeginUpdateResorce
fDiscard Long - TRUE (НЕнулевое значение) для отмены всех изменений, внесенных вызовами функции UpdateResource с момента последнего вызова BeginUpdateResorce. Если параметр равен нулю, все изменения, внесенными UpdateResource, записываються в файл.

Возвращаемое значение: Long - TRUE (НЕнулевое значение) в случае успеха, ноль при неудаче. Устанавливает информацию GetLastError.

Платформа: Windows NT


UpdateResorce
Объявление в VB: Declare Function UpdateResource Lib "kernel32" Alias "UpdateResourceA" (ByVal hUpdate As Long, ByVal lpType As String, ByVal lpName As String, ByVal wLanguage As Long, lpData As Any, ByVal cbData As Long) As Long
Описание: Функция позволяет модифицировать ресурсы в исполняемом файле или DLL.

Параметр тип/описание
hUpdate Long - манипулятор, возвращаемый функцией BeginUpdateResorce
lpType String или Long - тип ресурса: RT_BITMAP - растр, загружается функцией LoadBitmap, RT_FONT - Шрифт, используется функцией AddFontResource, RT_FONTDIR - каталог шрифтов, RT_RCDATA - Неструктурированный поток данных, RT_STRING - Строковый ресурс, загружается функцией LoadString, RT_MESSAGETABLE - таблица сообщений, RT_CURSOR - курсор загружается функцией LoadCursor, RT_GROUP_CURSOR - аппаратно-независимый курсор, RT_ICON - иконка загружается LoadIcon, RT_GROUP_ICON - аппаратно-независимый значок. Остальные в большинстве случаев не используються в VB.
lpName String или Long - новый идентификатор ресурса. При необходимости происходит замена существующего ресурса указанного типа с заданным идентификатором.
wLanguage Идентификатор языка ресурса.
lpData Any - адрес блока памяти, содержащего неструктурированные данные ресурса, внедряемые в файл. Строки должны храниться в кодировке Unicode. Используется ByVal 0&, что бы удалить существующий ресурс с заданным идентификатором.
cbData Long - количество байт в буфере lpData.
Возвращаемое значение: Long - НЕнулевое значение в случае успеха, ноль при неудаче. Устанавливает информацию GetLastError.

Платформа: Windows NT
взято с форума: http://forum.sources.ru/index.php?showtopic=101314&hl=
для Delphi примерно так же, синтаксис немного другой...
Si numqum quaeris, raro magister eris!
SOA

SOA (статус: Посетитель), 22 июня 2010, 08:24 [#13]:

To bugmenot: да в разделе Remarks, только там написано что первое слово должно быть равно не нулю а ffff, что является неправильным unicode символом.
If the first WORD in the member is equal to the value 0xffff, which is an invalid Unicode character, then the following WORD is a type number
Но все это касается типа ресурса, для которого вы мне уже подсказали макрос MAKEINTRESOURCE.

To Maksell: за функции спасибо, но у меня проблема не в них, а с самим форматом res файла, который я хочу создавать програмно из своего приложения, без использования brcc32.
SOA

SOA (статус: Посетитель), 22 июня 2010, 10:13 [#14]:

Пока что создаваемый файл ресурсов меньше создаваемого в brcc32 на 18 байт почемуто.
А при попытке прочитать размер данных и размер хидера из файла сгенерированного brcc32 выдается 0 и 32

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type Header = Record
DataSize:DWORD;
HeaderSize:DWORD;
RcType:DWORD;
NAME:PCHAR;
DataVersion:DWORD;
MemoryFlags:WORD;
LanguageId:WORD;
Version:DWORD;
Characteristics:DWORD;
End;

var
Form1: TForm1;
MyRes,SrcFile: TFileStream;
Heder:Header;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
Buf: BYTE;
Count: LongInt;
begin
i:=FileCreate('Resource.res');
FileClose(i);
MyRes:=TFileStream.Create('Resource.res',fmOpenWrite);
i:=1;
Heder.NAME:=PCHAR(IntToStr(i));//Имя текущего файла для записи в ресурсы
SrcFile:=TFileStream.Create(String(Heder.NAME+'.bmp'),fmOpenRead);
Heder.DataSize:=SrcFile.Size;// размер ресурса
Heder.RcType:=4294901762; // ffff0002 тип ресурса BITMAP
Heder.HeaderSize:=SizeOf(Heder);//размер описания ресурса

// записываем описание ресурса
MyRes.Write(Heder,SizeOf(Heder));

Count:=0;
//пишем сам ресурс

While Count<SrcFile.Size do
Begin
SrcFile.Read(Buf,1);
MyRes.Write(Buf,1);
Count:=Count+1;
End;

SrcFile.Free;
MyRes.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
Count: LongInt;
begin

if OpenDialog1.Execute=true then
SrcFile:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
SrcFile.Read(Heder.DataSize,SizeOf(Heder.DataSize));
SrcFile.Read(Heder.HeaderSize,SizeOf(Heder.HeaderSize));
Label5.Caption:=IntToStr(Heder.DataSize);
Label6.Caption:=IntToStr(Heder.HeaderSize);
//Label7.Caption:=Heder.RcType;
//Label8.Caption:=Heder.NAME;
SrcFile.Free;
end;

end.
SOA

SOA (статус: Посетитель), 24 июня 2010, 11:08 [#15]:

Все сделал !!!!!!!
:)))))))))))))))))))))))))))))
SOA

SOA (статус: Посетитель), 27 июня 2010, 13:06 [#16]:

Блин я статью написал по этой теме, когда опубликуют то?

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:54
Выполнено за 0.03 сек.