Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Dinamicko citanje i menjanje resourcestring-ova

[es] :: Pascal / Delphi / Kylix :: Dinamicko citanje i menjanje resourcestring-ova

[ Pregleda: 2434 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

looping
none
none

Član broj: 324206
Poruke: 18
95.180.97.*



Profil

icon Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 07:32 - pre 118 meseci
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.


 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 08:48 - pre 118 meseci
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;
 
Odgovor na temu

looping
none
none

Član broj: 324206
Poruke: 18
95.180.97.*



Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 12:44 - pre 118 meseci
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';

 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 14:27 - pre 118 meseci
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().
 
Odgovor na temu

looping
none
none

Član broj: 324206
Poruke: 18
95.180.97.*



Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 15:04 - pre 118 meseci
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
 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova15.07.2014. u 15:05 - pre 118 meseci
Ti resource stringovi imaju staticki ID, tako da ces morati da ih uporedjujes po ID-ju i menjas.
 
Odgovor na temu

looping
none
none

Član broj: 324206
Poruke: 18
95.180.97.*



Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova16.07.2014. u 10:30 - pre 118 meseci
Hvala na ideji, mislim da ce mi to resiti problem.
 
Odgovor na temu

looping
none
none

Član broj: 324206
Poruke: 18
37.19.108.*



Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova24.07.2014. u 12:28 - pre 117 meseci
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.
 
Odgovor na temu

reiser

Član broj: 7895
Poruke: 2314



+102 Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova24.07.2014. u 13:39 - pre 117 meseci
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
  ....
 
Odgovor na temu

looping
none
none

Član broj: 324206
Poruke: 18
37.19.108.*



Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova24.07.2014. u 15:30 - pre 117 meseci
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;
 
Odgovor na temu

savkic
Igor Savkić

Moderator
Član broj: 92186
Poruke: 2739



+92 Profil

icon Re: Dinamicko citanje i menjanje resourcestring-ova24.07.2014. u 22:03 - pre 117 meseci
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
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Dinamicko citanje i menjanje resourcestring-ova

[ Pregleda: 2434 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.