Zmiana stringu w zasobach

0

Witam

Kod

procedure TForm1.Button1Click(Sender: TObject);
var
Buff: array [0..MAX_PATH] of Char; 
begin
LoadString(hInstance, 65280, Buff, SizeOf(Buff));
label1.Caption := Buff;
end;

zapisuje do label1 treść odczytaną ze swojego zasobu 65280. A jak zmienić tę treść? Pytam o coś przeciwnego do tego, co podałem wyżej. Nie chcę odczytać, tylko zapisać do zasobu np.65280 wartość z label1.caption. Szukałem czegoś w stylu SaveString, ale niestety nic nie znalazłem.
Z góry dziękuję za pomoc.

0
jajakija napisał(a)

Witam

Kod

procedure TForm1.Button1Click(Sender: TObject);
var
Buff: array [0..MAX_PATH] of Char; 
begin
LoadString(hInstance, 65280, Buff, SizeOf(Buff));
label1.Caption := Buff;
end;

zapisuje do label1 treść odczytaną ze swojego zasobu 65280. A jak zmienić tę treść? Pytam o coś przeciwnego do tego, co podałem wyżej. Nie chcę odczytać, tylko zapisać do zasobu np.65280 wartość z label1.caption. Szukałem czegoś w stylu SaveString, ale niestety nic nie znalazłem.
Z góry dziękuję za pomoc.

Z tego co wiem to nie możesz nic zapisać do skompilowanego *.EXE
Przyczyna jest prosta kontrola CRC zapisanego pliku.
Możesz mieć w sasobie coś zapisać do pliku lub rejestru sytemu i tam swój pierwowzór zmieniać ale w orginalnym pliku *.EXE nie. Oczywiście nie jestem wyrocznią i mogę się mylić technologia idzie do przodu i pomysłowych programów nie brakuje.

0
abj napisał(a)

Z tego co wiem to nie możesz nic zapisać do skompilowanego *.EXE
Przyczyna jest prosta kontrola CRC zapisanego pliku.

dac to sie da, bo niby jakim cudem daje sie zmieniac np systemowe ikonki lub zmieniac jezyk programow?
z reszta nawet slynny ResourceHacker zostal w delphi napisany ;]
kontrola CRC? chyba tylko wtedy gdy sam program to robi (ze sprawdza samego siebie). przezkoda moze byc kompresja exe, np upx'em.

0

Tutaj http://4programmers.net/Forum/viewtopic.php?id=60489 znalazłem kod, jakiego mi potrzeba:

var
  hUpdateRes: THandle;
  Done: Boolean;
  Res: TResourceStream;

begin

  Res := // Tutaj trzeba załadować stringa z zasobów Twoich

  hUpdateRes := BeginUpdateResource(PCHAR('c:\plik.exe'), FALSE); // program gdzie będziemy zamieniać

  Done := UpdateResource(hUpdateRes, RT_STRING, 'stala_odwolujaca_sie_do_zasobu', LANG_NEUTRAL, Res.Memory, Res.Size); // Zamiana!

 EndUpdateResource(hUpdateRes, FALSE); // Koniec

end;

jednak nie wiem co wpisać w: Res := // Tutaj trzeba załadować stringa z zasobów Twoich
Wpisuję 65280 i pojawia się:[Error] Unit1.pas(49): Incompatible types: 'TResourceStream' and 'Integer'

0

Res := TResourceStream.Create + F1

0
Misiekd napisał(a)

Res := TResourceStream.Create + F1

Będę tak bardzo zabawny jak Ty i odpowiem: nie działa to co mi zaproponowałeś :(
Pewnie trudno Tobie uwierzyć, że nie wszyscy są tacy super jak Ty, ale szukam i nie wiem jak to zrobić.
Wpisuję:
res:=TResourceStream.Create(hinstance,'65282',RT_STring);
i przy próbie zapisu stringa do zasobu pojawia się błąd "Resource 65282 not found."

0

jak byś to napisał wcześniej to bym ci tak nie napisał. Ale nie lepiej napisać
"jednak nie wiem co wpisać w: Res := // "
i mieć pretensje.
Poza tym nie widzisz różnicy między '65282' a 65282????

I może trochę grzeczniej bo to ty masz problem a nie ja i to ty chcesz pomocy

0

"Poza tym nie widzisz różnicy między '65282' a 65282????"
Widzę. Widzę też błąd który pojawia się:"[Error] Unit1.pas(49): Incompatible types: 'String' and 'Integer'"
Wpisuję=TResourceStream.Create(hinstance,pchar(65282),RT_STring); i pojawia się z kolei błąd:
user image

"I może trochę grzeczniej bo to ty masz problem a nie ja i to ty chcesz pomocy"
Jestem grzeczny dla grzecznych, a póki co nic nie pomogłeś, tylko wprowadziłeś zamęt swoimi żarcikami i kłótniami. Jeśli oczekujesz, że będę się kajał bo potrzebuję pomocy, to w ogóle nie zaglądaj do tego tematu:)

0

dla mnie EoT
na pewno ktoś inny ci pomoże - mi się nie chce

0

Olesio już mi pomógł. Może przyda się jeszcze komuś w przyszłości:
http://4programmers.net/Forum/viewtopic.php?id=60489 właściwie można usunąć ten temat.

0

jajakija: nie dośc że nie jest zbyt uprzejmy i dublujesz wątki, odpisałem Tobie już w temacie pod adresem
http://4programmers.net/Forum/viewtopic.php?id=60489 bo do końca nie wiem jak rozwiązać Twój problem
jednak Ty robisz coś całkiem bez sensu jakbyś skorzystał z helpa jak Tobie Misiekd doradził wiedział byś, że
RT_STREING w parametrze do tworzenia TResourceStreama używane jest kiedy wczytujemy StringTable, no
a ale problemem pozostaje nazwa zasobu, na pewno napisanie PChar(IdZasobu) jest bez sensu - poczytaj
najpierw o typach i co to jest PChar. Ten parametr to nazwa zasobu lub jeśli tworzymy przez CreateFromID
to jego identyfikator liczbowy podany w pliku rc na przykład #1 podane w pliku to w programie dajemy 1, a
StringTable wczytuje się poprzez LoadString, bo jak byś zamiast chamsko się odności potestował trochę to
po takim kodzie oraz podejrzeniu nawet głupim ResHackerem swojego exeka byś wiedział, że StringTables
są indeksowane dla tak wyglądającego pliku rc jak poniżej kolejno 1, 2, 3 i tak dalej. Pozostale są wyżej.
Zapisując taki plik a.rc i używając poniższego kodu dostałem oddzielony zerami kawałek tekstu z yes i No.

STRINGTABLE
{
 1, "&Yes"
 2, "&No"
 17, "&Si"
 18, "&No"
 33, "&Ja"
 34, "&Nej"
}
{$R a.res}
var
  Res : TResourceStream;
begin
  Res := TResourceStream.CreateFromID(hInstance, 1, RT_STRING);
  Res.SaveToFile('D:\test.bin');
  Res.Free;
end;

Ale do ładowania stringów używa się LoadString. Do ich zapisu w exe musisz użyć takiego kodu jak niżej, w
sumie z moich testów wynika że działa ok. Po prostu pod ResHackiem sobie możesz zobaczyć jaki numer w
StringTables ma tablica stringów jaką chcesz podmienić i podawać zamiast '1' ten numer jako tekst. Czyli
Twój problem polegał na tym że zniechęciłeś całkiem MisiekD do pomocy, zamiast tak jak Ci radził zajrzeć
do Helpa. Nie wiem tylko czy taka podmiana stringtable na pewno zawsze zadziała ok, ale sam to sprawdź.

var
  hUpdateRes : THandle;
  Res : TResourceStream;
begin
  Res := TResourceStream.CreateFromID(hInstance, 1, RT_STRING);
  hUpdateRes := BeginUpdateResource(PCHAR('D:\test.exe'), False);
  UpdateResource(hUpdateRes, RT_STRING, '1', LANG_NEUTRAL, Res.Memory, Res.Size);
  EndUpdateResource(hUpdateRes, False);
end;

Oczywiście zamiast ResHackera możesz użyć innego edytora zasobów, jest ich trochę. A i StringTables jaką
podałem to przykładowa tablica wzięta z jakiegoś artykułu w google. W sumie w google jest to dośc dobrze
opisane, ale nie do końca. Moze pozostawiono pole do własnych prób, na które chyba Ty byłeś za leniwy ;/

EDIT: no zdążyłem po testach zakończyć posta, a jajakija już sobie chyba poradziłeś. Jak widzisz "problem"
był w sumie dosyć banalny i wniosek dla Ciebie żeby zawsze spojrzeć najpier do helpa oraz pogooglować :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1