Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/25: Рейтинг темы: голосов - 25, средняя оценка - 4.64
0 / 0 / 0
Регистрация: 25.04.2011
Сообщений: 20

UpdateResource

26.05.2011, 17:07. Показов 5351. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть файл ресурсов res.res. в нем всего 1 строка = "111", надо поменять ее скажем на "222". Пробую с помощью updateresource не выходит
Delphi
1
2
3
4
5
6
7
8
9
procedure TForm2.FormShow(Sender: TObject);
var res:hfile;
    s:pchar;
begin
     s:='222';
     res:=BeginUpdateResource('project2.exe',false);
     UpdateResource(res,RT_RCDATA,'res.res',LANG_NEUTRAL,s,21);
     EndUpdateResource(res,false);
end;
может что неправильно, подскажите и исправьте плиз, makelangid не определяет почему то. Жду советов...
 Комментарий модератора 
Теги кода добавлены модератором. По правилам форума, код должен быть оформлен соответствующими тегами. Для оформления кода Delphi следует выделить этот код и на панели редактирования сообщения нажать кнопку "DELPHI".
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.05.2011, 17:07
Ответы с готовыми решениями:

UpdateResource - редактирование ресурсов
Здравствуйте коллеги! В WinNt/2000/XP изменить ресурсы в exe-файлах можно с помощью функции UpdateResource. А как это же сделать в...

UpdateResource
Имею следующий код: function Resss:string; var hRes,hFile,MyFile,BytesWritten,hLRes :THandle; hUpd:THandle; ResSize:Dword; ...

UpdateResource +RT_STRING (Обновление в ресурсе строки)
Всем привет в чем проблема мне нужно обновить строку TCHAR * pString = _T("Hello"); HANDLE hResource; hResource =...

7
306 / 187 / 26
Регистрация: 14.02.2010
Сообщений: 547
26.05.2011, 19:37
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BOOL UpdateResource(
    HANDLE hUpdate, - Handle файла ресурсов, который вернула BeginUpdateResource
                              открываете project2.exe, а пишите "есть файл ресурсов res.res"
                              этот "res.res" является частью project2.exe?
    LPCTSTR lpType,   RT_RCDATA - сырые данные, а "111" - скорее всего записана как строка
    LPCTSTR lpName,  res.res - уверены, что это имя ресурса? (оно вовсе не обязано совпадать с именем файла)
    WORD wLanguage, - вроде как все ладно
    LPVOID lpData,     - "Pointer to the resource data to be inserted into the executable file. If the resource is one of the predefined
                               types, the data must be valid and properly aligned. Note that this is the raw binary data stored in the executable
                               file, not the data provided by LoadIcon, LoadString, or other resource-specific load functions. All data containing
                               strings or text must be in Unicode format; lpData must not point to ANSI data" - комментарии излишни. 
                               Передаете Delphi-строку, о которой WinAPI абсолютно ничего не знает, к тому же в непонятно какой 
                               кодировке
    DWORD cbData - Specifies the size, in bytes, of the resource data at lpData ("222" = 21 ???)
);
1
0 / 0 / 0
Регистрация: 25.04.2011
Сообщений: 20
26.05.2011, 20:20  [ТС]
res.res уже компилировал в project2. в файле строка описана так: stringtable { 1, "111" }. Скорее всего записал правда в ANSI, щас попробую в юникоде. 21 поставил от балды)

Если можно, напишите как должно все выглядеть
0
0 / 0 / 0
Регистрация: 25.04.2011
Сообщений: 20
26.05.2011, 20:35  [ТС]
В юникоде файл ресурсов не создается((( в res.rc файле прописал тоже самое, только кодировка юникод и не создает командой brcc32.exe res.rc, что же делать
0
306 / 187 / 26
Регистрация: 14.02.2010
Сообщений: 547
27.05.2011, 12:11
Задача в случае со строками оказалась не столь тривиальной. Весь вечер вчера уе...

LoadString для ресурсов есть, а вот WriteString я так и не отыскал,
Впрочем, если заменить всю таблицу строк одной строчкой, так тут без проблем,
вроде как даже автоматом проставляется нужная длина,
надо только правильно передать параметры, а вот замена отдельной строки...
Поэтому такая вот раскорячка...

во-первых, нигде не нашел ни описания brcc32, ни формата поддерживаемых им файлов
опытным путем выяснил, что нумеровать строки лучше с 1 и по порядку, иначе
имена и количество STRINGTABLE может быть произвольным - и придется дополнительно
изгаляться с нумерацией ресурсов, языков и прочей лабуды

пишем res.txt

Delphi
1
2
3
4
5
6
STRINGTABLE
{
  1, "Моя первая строка"
  2, "My String 2"
  3, "String 3"
}
компилирировать лучше явно задав язык (RUSSIAN - 19)
в этом случае SUBLANG получается 0
если компилить без языка, получается LANG_RUSSIAN,1
тогда в задании языка надо рисовать
Delphi
1
1 shl 10 or LANG_RUSSIAN
как задать в самом STRINGTABLE язык - не сумел понять,
MS-описание формата brcc32 упорно не кушает

компилим
brcc32 -l0019 res.txt

собираем .exe

ну и вот то, что насочинял
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
function GetSysErrStr: string;
var
  ErrBuff: PChar;
begin
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
                nil, GetLastError, 0, @ErrBuff, 0, nil);
  Result := ErrBuff;
  LocalFree(HLOCAL(ErrBuff));
end;
 
procedure Err(const capt: PChar = nil);
begin
  MessageBox(GetActiveWindow, PChar(GetSysErrStr), capt, MB_ICONERROR);
end;
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
  hExe: THandle;
  hRes: HRSRC;
  hLoadRes: HGLOBAL;
 
  buf, pR, pW: PWideChar;
  rLen, sLen: Integer;
 
  newString: WideString;
 
const
  strFind: PWideChar = 'My String 2'; // что будем менять
  tableNum = 1;
begin
  newString := 'Моя новая строка';  // чем менять
 
  // читаем все строки этой STRINGTABLE, если это строка, которую надо менять,
  // в буфер пишем новую строку, иначе - прочитанную. Перед строкой идет слово
  // длины строки в символах. Кроме того, таблица начинается со слова 0
 
  hExe := LoadLibrary('123.exe');
  if hExe <> 0 then begin
    // определяем размер строковой таблицы
    hRes := FindResource(hExe, MakeIntResource(tableNum), RT_STRING);
    if hRes <> 0 then begin
      rLen := SizeofResource(hExe, hRes);
      if rLen > 0 then begin
        hLoadRes := LoadResource(hExe, hRes);
        if hLoadRes > 0 then begin
 
          GetMem(buf, rLen + Length(newString)*SizeOf(WideChar));
 
          pR := PWideChar(hLoadRes);
          pW := buf;
          pWord(pW)^ := 0; // первое слово = 0
          Inc(pW);
 
          // читаем строки
          while rLen > 0 do begin
            sLen := pWord(pR)^;
            Dec(rLen, SizeOf(Word));
            Inc(pR);
            if sLen > 0 then begin // в конце опять могут пойти нули-их игнорим
              if CompareMem(pR, strFind, sLen*SizeOf(WideChar)) then begin
                // наша
                pWord(pW)^ := Length(newString);  // длина
                Inc(pW);
                CopyMemory(pW, @newString[1], Length(newString) * SizeOf(WideChar));
                Inc(pW, Length(newString));
              end else begin
                // не наша
                pWord(pW)^ := sLen;
                Inc(pW);
                CopyMemory(pW, pR, sLen * SizeOf(WideChar));
                Inc(pW, sLen);
              end;
              Dec(rLen, sLen * SizeOf(WideChar));
              Inc(pR, sLen);
            end;
          end; // while
 
          FreeLibrary(hExe); // иначе не даст обновить
          hExe := 0;
 
          hExe := BeginUpdateResource('123.exe', False);
          if hExe <> 0 then begin
            if UpdateResource (hExe,
                            RT_STRING,
                            MakeIntResource(tableNum),
                            LANG_RUSSIAN,
                            buf,
                            (pW - buf)*SizeOf(WideChar)) then begin
              if EndUpdateResource(hExe, False) then begin
                MessageBox(GetActiveWindow, 'Да', 'Таки да', MB_OK);
              end else
                Err('EndUpdateResource');
              hExe := 0;
            end else
              Err('UpdateResource');
          end else
            Err('BeginUpdateResource');
 
          FreeMem(buf);
        end else
          Err('LoadResource');
      end else
        Err('SizeofResource');
    end else
      Err('FindResource');
  end;
 
  if hExe <> 0 then
    FreeLibrary(hExe);
end;
1
0 / 0 / 0
Регистрация: 25.04.2011
Сообщений: 20
28.05.2011, 11:25  [ТС]
Пожалуй для моей простенькой проги и для моего мозга это чересчур
Сделаю тогда просто через текстовый файл. Кстати не знаешь как зашифровать и потом расшифровать текст в файле, чтобы посторонние не смогли разобрать. Может есть какой-нибудь стандартный компонент или функция, с кодом не хочу заморачиваться.
Описал переменную так
var f:text;
0
306 / 187 / 26
Регистрация: 14.02.2010
Сообщений: 547
28.05.2011, 18:28
Цитата Сообщение от Romeo1990 Посмотреть сообщение
Пожалуй для моей простенькой проги и для моего мозга это чересчур
Если что неясно, могу пояснить, хотя там комментариев достает. Много времени убил на поиск "WriteString"? пока не дошло, что из ресурсов только читают, а пишут туда как правило специальными инструментами, поэтому такой функции может вообще не быть в природе.

А по поводу шифрования, так если Вас не устраивают решения, которых в Internete пруд пруди, и нужен непременно текстовый файл, то можно при записи просто менять каждый символ на, скажем, предыдущий, а при чтении - наоборот. Ну или сделать таблицы перекодировки - см.пример. Ломаться, конечно, такие "шифры" будут на раз.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
unit MainU;
 
interface
 
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.DFM}
 
const
  mask: array [10..255] of Char = (
      #167, #099, #114, #005, #096, #115, #143, #137, #069, #018, #140, #180, #045, #218, #076, #252,
      #133, #024, #166, #093, #157, #095, #102, #232, #035, #022, #119, #208, #123, #196, #053, #186,
      #144, #048, #152, #129, #015, #103, #007, #159, #138, #162, #087, #090, #240, #109, #116, #234,
      #191, #161, #142, #217, #049, #077, #052, #055, #182, #239, #079, #064, #094, #164, #027, #225,
      #030, #247, #075, #251, #091, #001, #112, #237, #171, #051, #108, #042, #169, #032, #062, #178,
      #219, #012, #020, #082, #061, #057, #148, #158, #104, #165, #181, #017, #044, #124, #063, #147,
      #068, #067, #135, #244, #080, #081, #084, #004, #211, #145, #242, #210, #198, #254, #223, #199,
      #050, #085, #168, #006, #175, #243, #185, #092, #132, #060, #025, #028, #047, #228, #192, #206,
      #065, #189, #236, #130, #221, #011, #026, #117, #106, #209, #200, #036, #014, #127, #188, #214,
      #246, #250, #066, #249, #034, #207, #220, #233, #179, #195, #089, #040, #172, #187, #146, #083,
      #150, #136, #113, #202, #054, #105, #149, #248, #111, #019, #227, #193, #088, #174, #253, #043,
      #101, #213, #203, #058, #041, #235, #126, #086, #029, #245, #176, #059, #224, #222, #037, #141,
      #151, #070, #226, #118, #215, #120, #131, #021, #201, #194, #071, #074, #078, #212, #009, #241,
      #154, #153, #160, #205, #046, #230, #197, #016, #139, #229, #128, #121, #183, #008, #097, #107,
      #100, #173, #073, #125, #031, #216, #190, #231, #177, #163, #072, #156, #098, #184, #038, #170,
      #155, #056, #033, #204, #238, #122
);
 
// â ýòîì ìàññèâå íå äîëæíû ñîâïàäàòü çíà÷åíèÿ ñ èõ "íàñòîÿùèìè", êðîìå òîãî,
// íå äîëæíî áûòü íóëåâûõ áàéòîâ,
// òàêæå íå äîëæíî áûòü ñèìâîëîâ ïåðåâîäîâ ñòðîê, õîòÿ ìîæíî è ïåðåäåëàòü àëãîðèòì Decode,
// äîáàâëÿÿ ê âõîäíîé ñòðîêå ýòè ñèìâîëû, è òîëüêî ïîòîì äåêîäèðóÿ
// çàïîëíÿòü ðó÷êàìè òàêîé ìàññèâ, êîíå÷íî, âëîì, ïîýòîìó
// âñïîìîãàòåëüíàÿ, ÷òîáû íàðèñîâàòü mask
procedure MakeMask;
var
  k, m, v: Integer;
  mask: array [10..255] of Char;
  f: TextFile;
 
  // ïðîâåðêà îòñóòñòâèÿ val â çíà÷åíèÿõ mask îò íà÷àëà ìàññèâà äî last
  function InMask(val: Char; last: Integer): Boolean;
  var
    idx: Integer;
  begin
    for idx := Low(mask) to last do begin
      if mask[idx] = val then begin
        Result := True;
        Exit;
      end;
    end;
    Result := False;
 
  end;
 
begin
  // íîëü íàì òîæå íå íóæåí
  for k := Low(mask) to High(mask) do
    mask[k] := #0;
 
  Randomize;
  v := 0; // ÷òîáû íå òàðàõòåë êîìïèëÿòîð
  for k := Low(mask) to High(mask) do begin
    // ïîëó÷àåì óíèêàëüíûå ñèìâîëû, ïîçèöèè êîòîðûõ â mask íå ñîâïàäàþò
    // ñ èõ çíà÷åíèåì, à òàêæå îòëè÷íûå îò 0, 10 è 13
    while (v in [10, 13, Byte(k)]) or InMask(Char(v), k) do
      v := Random(255);
    mask[k] := Char(v);
  end;
 
  // çàïèñûâàåì â ôàéë, èõ êîòîðîãî ïîòîì Copy-Paste â mask
  AssignFile(f, ExtractFilePath(Application.ExeName) + 'my.enc');
  Rewrite(f);
  m := 0;
  for k := Low(mask) to High(mask) do begin
    Write(f, Format('#%0.3d, ', [Ord(mask[k])]));
    Inc(m);
    if m = 16 then begin
      WriteLn(f);
      m := 0;
    end;
  end;
  CloseFile(f);
 
end;
 
// ôóíêöèÿ êîäèðîâàíèÿ
function EnCode(const src: string): string;
var
  idx: Integer;
begin
  SetLength(Result, Length(src) + 2); // äîáàâëÿåì ê ñòðîêå ñèìâîëû #13#10 ïåðåâîäà ñòðîêè
 
  idx := 1;
  while idx <= Length(src) do begin
    // çàìåíÿåì ñèìâîëû èñõîäíîé ñòðîêè íà èõ ñîîòâåòñòâèÿ èç mask
    Result[idx] := mask[ Ord(src[idx]) ];
    Inc(idx);
  end;
  // äîáàâëÿåì ñèìâîëû #13#10
  Result[idx] := mask[13];
  Inc(idx);
  Result[idx] := mask[10];
end;
 
// äåêîäèðîâàíèå
function DeCode(const src: string): string;
var
  idx: Integer;
 
  // èùåò â mask çíà÷åíèå, ñîâïàäàþùåå ñ mask è âîçâðàùàåò ñèìâîë, ñîîòâåòñòâóþùèé íàéäåííîé ïîçèöèè
  function FromMask(val: Char): Char;
  var
    idx: Integer;
  begin
    for idx := Low(mask) to High(mask) do begin
      if mask[idx] = val then begin
        Result := Char(idx);
        Exit;
      end;
    end;
    Result := #0;
  end;
 
begin
  SetLength(Result, Length(src));
  idx := 1;
  while idx <= Length(src) do begin
    Result[idx] := FromMask(src[idx]);
    Inc(idx);
  end;
 
  {
  // åñëè íàäî óäàëÿòü äîáàâëåííûé íàìè ïåðåâîä ñòðîêè, òî
  // ïðîöåäóðó ìîæíî íåìíîãî ïåðåäåëàòü
  SetLength(Result, Length(src)-2);
  idx := 1;
  while idx <= Length(src)-2 do begin
    Result[idx] := FromMask(src[idx]);
    Inc(idx);
  end;
  }
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  inF, outF: TextFile;
  s: string;
begin
  AssignFile(inF, ExtractFilePath(Application.ExeName) + 'MainU.pas');
  Reset(inF);
 
  AssignFile(outF, ExtractFilePath(Application.ExeName) + 'MainU.enc');
  Rewrite(outF);
 
  while not Eof(inF) do begin
    ReadLn(inF, s);
    Write(outF, EnCode(s));
  end;
  CloseFile(inF);
  CloseFile(outF);
 
 
  AssignFile(inF, ExtractFilePath(Application.ExeName) + 'MainU.enc');
  Reset(inF);
 
  AssignFile(outF, ExtractFilePath(Application.ExeName) + 'MainU.dec');
  Rewrite(outF);
 
  while not Eof(inF) do begin
    ReadLn(inF, s);
    Write(outF, DeCode(s));
  end;
  CloseFile(inF);
  CloseFile(outF);
 
  Close;
end;
 
end.
Добавлено через 10 минут
После нажатия на кнопку в каталоге программы у Вас окажутся два файла MainU.enc - закодированный, и MainU.dec - раскодированный

Единственно, я не предусмотрел проверку на валидность входных символов для обеих процедур - в том смысле, что код символа всегда должен быть не менее 10. По идее в строке и не должно быть таковых, но все-таки надо бы добавить. То, чего не может быть, бывает, да и не так уж редко...
2
0 / 0 / 0
Регистрация: 25.04.2011
Сообщений: 20
29.05.2011, 11:46  [ТС]
Спасибо за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.05.2011, 11:46
Помогаю со студенческими работами здесь

Изменение данных в ресурсах исполняемом-файле средствами UpdateResource
Господа, не получается обновить ресурсы в готовом exe-шнике на лету. Суть задачи в следующем: при запуске программы в комбобоксах...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru