Autor Beitrag
X-Mailer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 09:38 
Programm von mir.

barret.plusboard.de/textfromsource-f6.html

Findet Texte in Delphi *.pas Dateien wie z.B.
Button1.caption:='Hallo';

ersetzt diese durch einen Funktionsaufruf z.B.
Button1.caption:=TXT(1) {##Hallo##};

Erstellt eine Funktion names TXT am Anfang des Quellcodes
in der alle gefundenen Texte in einer Stringliste gesammelt werden.

Mit dieser Stringliste kann man jetzt z.B. das Programm schneller in andere Sprachen Übersetzten

oder die Texte verschlüsseln so das diese in der compilierten EXE nicht mehr sichtbar sind.

oder die Texte mit TXTs.Savetofile('c:\text.txt'); speichern

Kleine Verschlüsselungsroutine ist gleich mit dabei

Beispiel :

Quelltext OHNE Textfromsoure , Vorher :
ausblenden volle Höhe Delphi-Quelltext
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:
unit demo;

// use this demo application to play around with textfromsource

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 s:string;
begin
 //---- 'dont find this text'---
 button1.caption:='This is my Text'{ this is a word
 wrap remark to be 'ignored' }


 form1.caption:='Test';

 S:='Hello ''dear'' friend';  // ignore double '' 

 copyfile(PChar(Paramstr(0)),'.\test.exe',false); { add 'PChars' for Windows function calls }

 S:=copy( 'I say ' + S + ' to the World' ,1,40);  (* add no 'PChars' in function with "+"  *)

 label1.Caption:='Test'+' :  '+S;  // find Text 'Test' 2x in this Source, add only one time to stringlist

 label2.caption:='''http://www.xyz.de''';   
end;

end.



Quelltext MIT Textfromsoure , Nachher :

ausblenden volle Höhe Delphi-Quelltext
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:
unit demo;

// use this demo application to play around with textfromsource

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);  {##Free Stringlist##}
  private
    function TXT(TXTNr:integer):String;  {##Textstrings##}
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  TXTs: TStringlist; {##extracted text from Source##}
  Form1: TForm1;

implementation

{$R *.dfm}


{#### TEXT-STRINGS FROM SOURCE  http://sourceforge.net/projects/textfromsource/ ####} 
function TForm1.TXT(TXTNr:integer):String;
begin
 if not Assigned(TXTs) then
 begin
  TXTs:=Tstringlist.create;
  with TXTs do begin
{0}      Add('This is my Text');
{1}      Add('Test');
{2}      Add('Hello ''dear'' friend');
{3}      Add('.\test.exe');
{4}      Add('I say ');
{5}      Add(' to the World');
{6}      Add(' :  ');
{7}      Add('''http://www.xyz.de''');
  endend;
 Result := TXTs[TXTNr];
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  TXTs.free;  {##Free Stringlist##}
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 s:string;
begin
 //---- 'dont find this text'---
 button1.caption:=TXT(0{##This is my Text##} ; { this is a word
 wrap remark to be 'ignored' }


 form1.caption:=TXT(1{##Test##} ;

 S:=TXT(2{##Hello ''dear'' friend##} ;  // ignore double '' 

 copyfile(PChar(Paramstr(0)),PChar(TXT(3{##.\test.exe##} ),false); { add 'PChars' for Windows function calls }

 S:=copy( TXT(4{##I say ##}  + S + TXT(5{## to the World##}  ,1,40);  (* add no 'PChars' in function with "+"  *)

 label1.Caption:=TXT(1{##Test##} +TXT(6{## :  ##} +S;  // find Text 'Test' 2x in this Source, add only one time to stringlist

 label2.caption:=TXT(7{##''http://www.xyz.de''##} ;   
end;

end.




Mit Textfromsource und Verschlüsselung :

ausblenden volle Höhe Delphi-Quelltext
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:
unit demo;

// use this demo application to play around with textfromsource

interface

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

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);  {##Free Stringlist##}
  private
    function TXT(TXTNr:integer):String;  {##Textstrings##}
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  TXTs: TStringlist; {##extracted text from Source##}
  Form1: TForm1;

implementation

{$R *.dfm}
 
{#### TEXT-STRINGS FROM SOURCE  http://sourceforge.net/projects/textfromsource/ ####} 
function TForm1.TXT(TXTNr:integer):String;
 
 // Decryption  
 function D(S1:String):string;
 var i,t,po,Ra:integer;  x1,x2,s3:string; s2:char;
 begin
    X1:='ÿeTröXnküVpCBß#7(iv%u-F5R$QcEy8).t&ÄJÖI§g;h,GU0:l?b/P=SjoZaÜ9D*wm3x@f!qzK6NO14WY MLsAdHä2'; X1:=X1+X1+X1+X1+X1+X1+X1+X1;
    X2:='!wJAe-.30j=#8b)p:FöIz2ZRY&W/QKMüifNxÜhVt1(kr;ÖÄ9m5DlHE§@4?7,ScCnUqdXugLaß6vO$oäs%B *ÿTPyG'; X2:=X2+X2+X2+X2+X2+X2+X2+X2;
    S3:='';
    case S1[1of
      'A'..'Z' : Ra:=ord(S1[1])-65+20;
      'a'..'z' : Ra:=ord(S1[1])-97;
    end//case
    S1:=copy(S1,Ra+2,length(S1));
    for t:=1 to length(S1) do
    begin
     X2:=copy(x2,t,length(x2)-t+1) + copy(x2,1,t-1);
     po:=pos(S1[t],x2);
     if po>0 then S2:=x1[po] else S2:=S1[t];
     if S2='ÿ' then S2:=#39;
     S3:=S3+S2;
    end//for t
    while pos(#39#39,S3)>0 do delete(S3,pos(#39#39,S3),1);
    Result:=S3;
 end//Decryption
 
begin
 if not Assigned(TXTs) then
 begin
  TXTs:=Tstringlist.create;
  with TXTs do begin
{0}      Add(D('RTRu§HDü&xHwZ Aw*öjC§i63E.ÄKÜtn!:wwn87Jrz!wipI#vÄusu5'));     {##This is my Text##}
{1}      Add(D('FP1lL#6aBy;58WPerIvnL/,/9KJJPt'));                            {##Test##}
{2}      Add(D('GJ)mJjTx7 jAbhWCR@(SuvFF*9:PJl§d.2QiÄYgäJ3=DB*öQ'));          {##Hello ''dear'' friend##}
{3}      Add(D('KAf##MyyL$xö&Ä%emXISQ%k44k:7Ndsi\Ü3emEKbÄ'));                 {##.\test.exe##}
{4}      Add(D('Es8Ä:45)LT6jEd3,Bx*u *0Ö-VBPUt.'));                           {##I say ##}
{5}      Add(D('fT.aÖ%%N,Pr?ZI&87&v'));                                       {## to the World##}
{6}      Add(D('qnknh /ÄAlTAMF::.%m*P'));                                     {## :  ##}
{7}      Add(D('LLMuIqP?u$kwÜYYF.MÜo?P3%*lwA&q%V!wÖtr&usyIK12HvNDqW;Q§Oj'));  {##''http://www.barret.de''##}
  endend;
 Result := TXTs[TXTNr];
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  TXTs.free;  {##Free Stringlist##}
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 s:string;
begin
 //---- 'dont find this text'---
 button1.caption:=TXT(0{##This is my Text##} ; { this is a word
 wrap remark to be 'ignored' }


 form1.caption:=TXT(1{##Test##} ;

 S:=TXT(2{##Hello ''dear'' friend##} ;  // ignore double '' 

 copyfile(PChar(Paramstr(0)),PChar(TXT(3{##.\test.exe##} ),false); { add 'PChars' for Windows function calls }

 S:=copy( TXT(4{##I say ##}  + S + TXT(5{## to the World##}  ,1,40);  (* add no 'PChars' in function with "+"  *)

 label1.Caption:=TXT(1{##Test##} +TXT(6{## :  ##} +S;  // find Text 'Test' 2x in this Source, add only one time to stringlist

 label2.caption:=TXT(7{##''http://www.barret.de''##} ;   
end;

end.
Einloggen, um Attachments anzusehen!


Zuletzt bearbeitet von X-Mailer am Do 22.05.08 19:26, insgesamt 3-mal bearbeitet
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 20.05.07 10:14 
Nette Idee :zustimm:.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
X-Mailer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 11:26 
Danke, ich habe das Programm schon für meine eigenen Projekte benutzt,
siehe RegRunner und X-Mailer Source
www.delphi-forum.de/...utzt+INDY_72941.html
www.delphi-forum.de/...eintraege_72940.html

Bei X-Mailer zur Übersetzung Deutsch / Englisch

Bei Regrunner zur besseren Übersicht aller enthaltenen Strings.

Gruss Bernd


Zuletzt bearbeitet von X-Mailer am Do 22.05.08 19:28, insgesamt 1-mal bearbeitet
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: So 20.05.07 12:26 
Hallo,

schön, aber es fehlt noch das Freigeben der Stringliste.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
X-Mailer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 12:31 
Du hast natürlich recht, das wäre noch sauberer...

Dazu beötigt es ein onclose Event, das vieleicht noch gar nicht im Original-Source enthalten ist. Das wollte ich jetzt nicht einfach dazufummeln.

Ausserdem kann dies zu Problemen führen :
Wenn du das Programm längere Zeit nutzt dann wirst du schnell dazu übergehen bei Projekten die mehrere Forms haben die gefundenen Texte gemeinsam in mehreren Forms zu nutzen. Schließt du dann ein Formular auf dessen Texte ein anderes Zugreift gibt es Probleme.

Beipiel :

Du hast ein Programm mit 3 Formularen, Form1, Form2 und Form3.

Form2 hat eine Textliste "TXT2" , Form3 hat eine Textliste "TXT3"
wenn du gleiche Texte in Form2 und Form3 hats wirst du um den Pflegeaufwand zu minimieren schnell dazu übergenen anstelle von

--- Form2 TXT2 ---
..
{177} Add('Bitte geben Sie Ihren Namen ein');
..
-------------


--- Form3 TXT3 ---
..
{13} Add('Bitte geben Sie Ihren Namen ein');
..
-------------

dann dies Form3 dies zu schreiben :

--- Form3 TXT3 ---
..
{13} Add(Form2.TXT2(177)); // Bitte geben Sie Ihren Namen ein
..
-------------

Schließt du jetzt Form2 und werden die Texte von Form2 freigegeben dann erstellt Form3 die Stringliste doch wieder neu beim Aufruf von Form2.TXT2(177)...

Daher ist es sinnvoll die Freigabe manuell zu steuern, z.B. hier in Form1
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: So 20.05.07 13:54 
ich finde es etwas... erm.. unsinnig, jedesmal, wenn ein Text benötigt wird, die TXT die Liste erstellen zu lassen. Das sollte einmal passieren (die Texte ändern sich ja zur Laufzeit nicht!) und dann immer nur auf diese Liste zugreifen und dann am Ende freigeben.

Ausserdem, wenn Lannes sagt, es fehle das Freigeben der Stringliste, dann meinte er nicht im Close in Deinem Fall, sondern am Ende der Routine. Debugge das, was Du geschrieben hast, doch mal. So wie ich das im Source sehen, erstellst Du die StringList bei jedem Aufruf von Text, gibst sie aber nicht frei und in deinem Beispiel rufst Du TXT öfters auf ;) Damit erzeugst Du 'ne Menge memory leaks...

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Lannes
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: So 20.05.07 14:27 
Hallo,

es wird nicht jedesmal eine neue StringListe erstellt, :wink: und nein, ich meinte nicht am Ende der Routine, denn dann würde die Prüfung mit if not Assigned(TXTs) then immer True ergeben und infolge dessen jedesmal eine neue StringListe erstellt werden.
Dachte da eher an OnDestroy der MainForm.

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
X-Mailer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 15:03 
Lannes, du bist der Beste... stimmt alles
Endlich einer der mich versteht :-)
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: So 20.05.07 15:04 
stimmt, die Zeile muss ich übersehen haben ;)

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Calculon
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 676

Win XP Professional
Delphi 7 PE, Delphi 3 PRO
BeitragVerfasst: So 20.05.07 15:38 
Hi, finde die Idee auch gut.

Kriege bei einer Konsolenanwendung aber den Fehler

Zitat:

---------------------------
Informationen
---------------------------
done ! No new Strings found.
---------------------------
OK
---------------------------

Dann kickt mich das Programm raus...

Gruß

Calculon
--
X-Mailer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 17:45 
Das Programm geht von einer PAS Datei aus die von einem Delphi Formular stammt.

Sucht erst ab "{$R *.dfm}" , wenn dies nicht im Source vorkommt findet es auch nichts.

Diesen Suchstring kannst du aber einstellen nachdem die PAS Datei geladen wurde
und ggf. an dein Programm anpassen, z.B. die REM-Zeile //TFS in dein Programm einfügen

.
. hier nicht suchen
.
//TFS
.
. hier nach text suchen
.

und bei "insert function after :" //TFS eingeben. Dann sucht es beginnend AB diesem Marker nach Texten abwärs im Source.


--> Falls das auch nicht hilft, kopiere den Interface Teil bis zur Zeile {$R *.dfm} vom Demo provisorisch oben in deinen Source. Den kannst du ja hinterher wieder rauslöschen.


----

An die Anderen :

Neue Version Build 17 mit FormDestroy / TXTs.free ist fertig :-)

Ist im Beitrag oben neu eingepflegt.
Calculon
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 676

Win XP Professional
Delphi 7 PE, Delphi 3 PRO
BeitragVerfasst: So 20.05.07 20:36 
..jo, und dann alle 'Form1.' - strings löschen und dann geht's..

[OT]Lang lebe UltraEdit![/OT]
X-Mailer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 20
Erhaltene Danke: 1



BeitragVerfasst: So 20.05.07 21:27 
Na also, geht doch :-)
Kannst ja auch meinen Source auf deine Anforderungen anpassen.