|
[ looping @ 15.07.2014. 07:32 ] @
| Pozdrav svima,
pokisavam da u DELPHI-ju u runtime-u procitam sve resourcestring-ove iz exe ili bpl file-a i da po potrebi promenim njihove vrednosti. Znam da je to moguce ali ne uspevam da pronadjem kako.
Mogu da izmenim pojedinacni resurs, kao sto je prikazano u kodu ispod, ali ne mogu da dobijem grupu resursa i da petljom prolazim kroz svaki resurs.
Kako da iteriram kroz sve resoursestring-ove?
Code:
procedure HookResourceString(rs: PResStringRec; newStr: PChar);
var
oldprotect: DWORD;
begin
VirtualProtect(rs, SizeOf(rs^), PAGE_EXECUTE_READWRITE, @oldProtect);
rs^.Identifier := Integer(newStr);
VirtualProtect(rs, SizeOf(rs^), oldProtect, @oldProtect);
end;
initialization
HookResourceString(@resourceLabela, 'Nova vrednost');
end.
|
[ reiser @ 15.07.2014. 08:48 ] @
Zanimljiv problem. Evo ovako nesto ce ti enumerisati sve resurse koje zelis za odredjeni modul:
Code:
function EnumResourceNamesCallback(hModule: HMODULE; lpszType: LPCTSTR; lpszName: LPTSTR; lParam: LONG_PTR): BOOL; stdcall;
var
id: LongInt;
min, max: Integer;
C1: Integer;
buffer: PChar;
len: Word;
resource_stream: TResourceStream;
list: TStrings;
rstr: String;
begin
list := TStrings(lParam);
// special handling for RT_STRING resource type
// RT_STRING resource IDs are always in 1-$FFFF range
if LongInt(lpszName) <= $FFFF then
begin
id := LongInt(lpszName); // RT_STRING ID: %d [id]
min := (id - 1) * 16;
max := (id * 16) - 1;
resource_stream := TResourceStream.CreateFromID(hModule, id, RT_STRING);
try
buffer := resource_stream.Memory;
for C1 := min to max do
begin
len := Word(buffer^);
if len > 0 then
begin
SetString(rstr, buffer + 1, len);
// String ID %d: %s [C1, rstr]
list.Add(rstr);
Inc(buffer, len + 1);
end
else
Inc(buffer);
end;
finally
resource_stream.Free;
end;
end
else
list.Add(String(lpszName));
result := TRUE;
end;
procedure EnumResources(const AModule: HMODULE; const AList: TStrings);
begin
EnumResourceNames(AModule, RT_STRING, @EnumResourceNamesCallback, NativeInt(AList));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
resource_list: TStringList;
begin
resource_list := TStringList.Create;
try
EnumResources(HInstance, resource_list);
ShowMessage(resource_list.Text);
finally
resource_list.Free;
end;
end;
[ looping @ 15.07.2014. 12:44 ] @
Hvala na odgovoru, primer koji si dao radi upravo ono sto sam i zeleo, daje listu resursa.
A da li postoji nacin da pored vrednosti resursa dobijem i ime labele kako je definisana u *.pas fileu,
na pr. da dobijem prvi= 'Ovo je prvi string', drugi = 'Ovo je drugi string'?
Code:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
resourcestring
prvi = 'Ovo je prvi string';
drugi = 'Ovo je drugi string';
[ reiser @ 15.07.2014. 14:27 ] @
99% sam siguran da to nije moguce. Jedino sto mozes da probasj e da ih deklarises kao var (nisam siguran da li ti je resourcestring bas potreban?), deklarises ID svakog stringa i onda koristis LoadStr().
[ looping @ 15.07.2014. 15:04 ] @
Pa ono sto treba da uradim je da u vec postojecem projektu, prilikom startovanja aplikacije dinamiski izmenim resourcestring-ove.
Zahtev je da se sve vrednosti resourcestring-ova smete u bazi i da se prilikom startovanja aplikacije, vrednosti resourcestring-ova koje su definisane prilikom dizajniranja, zamene sa vrednostima iz baze
[ reiser @ 15.07.2014. 15:05 ] @
Ti resource stringovi imaju staticki ID, tako da ces morati da ih uporedjujes po ID-ju i menjas.
[ looping @ 16.07.2014. 10:30 ] @
Hvala na ideji, mislim da ce mi to resiti problem.
[ looping @ 24.07.2014. 12:28 ] @
Na nesrecu, ponovo sam primoran da konsultujem bolje od mene u DELPHI-ju
Kako je Reiser objasnio, mogu da dobijem spisak svih resourcestringova u TStringList objektu,
ali ja nikako nisam pronasao nacin da te resourcestringove i izmenim kasnije prolazeci kroz perlju.
Da li postoji nacin i to da se uradi kroz petlju ili cu ipak morati svaki resource string posebno, kao sto je prikazano ispod:
Code:
resourcestring
resourceLabela_1 = 'Inicijalna vrednost_1';
resourceLabela_2 = 'Inicijalna vrednost_2';
.
.
resourceLabela_n = 'Inicijalna vrednost_n';
procedure HookResourceString(rs: PResStringRec; newStr: PChar);
var
oldprotect: DWORD;
begin
VirtualProtect(rs, SizeOf(rs^), PAGE_EXECUTE_READWRITE, @oldProtect);
rs^.Identifier := Integer(newStr);
VirtualProtect(rs, SizeOf(rs^), oldProtect, @oldProtect);
end;
initialization
HookResourceString(@resourceLabela_1, 'Nova vrednost_1');
HookResourceString(@resourceLabela_2, 'Nova vrednost_1');
.
.
HookResourceString(@resourceLabela_n, 'Nova vrednost_1');
end.
[ reiser @ 24.07.2014. 13:39 ] @
Pre linije len := Word(buffer^);, ako taj buffer castujes u PResStringRec, dobijas pointer ka tom string resursu:
Code:
var
prsr: PResStringRec;
begin
...
for C1 := min to max do
begin
prsr := @buffer;
// ChangeResource(prsr, 'bla');
len := Word(buffer^);
if len > 0 then
....
[ looping @ 24.07.2014. 15:30 ] @
Stavio sam kao sto si rekao ali na ovaj nacin ne menja resourcestring-ove, tj. ostaju onakvi kakvi su definisani u *.pas fileu
Izgleda da gresim negde
Stavio sam ovko
Code:
var
id: LongInt;
min, max: Integer;
C1: Integer;
buffer: PChar;
len: Word;
resource_stream: TResourceStream;
list: TStrings;
rstr: String;
prsr: PResStringRec;
begin
list := TStrings(lParam);
// special handling for RT_STRING resource type
// RT_STRING resource IDs are always in 1-$FFFF range
if LongInt(lpszName) <= $FFFF then
begin
id := LongInt(lpszName); // RT_STRING ID: %d [id]
min := (id - 1) * 16;
max := (id * 16) - 1;
resource_stream := TResourceStream.CreateFromID(hModule, id, RT_STRING);
try
buffer := resource_stream.Memory;
for C1 := min to max do
begin
prsr := @buffer;
HookResourceString(prsr, 'bla');
len := Word(buffer^);
if len > 0 then
begin
SetString(rstr, buffer + 1, len);
// String ID %d: %s [C1, rstr]
list.Add(rstr);
Inc(buffer, len + 1);
end
else
Inc(buffer);
end;
finally
resource_stream.Free;
end;
end
else
list.Add(String(lpszName));
result := TRUE;
[ savkic @ 24.07.2014. 22:03 ] @
Resursi se menjaju preko odgovarajućih WinApi funkcija, međutim to i ne funkcioniše uvek kako treba. Moj ti je savet da koristiš madRes za tu svrhu jer lepo radi a i besplatan je.
http://help.madshi.net/madResUnit.htm
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|