Entwickler-Ecke

Open Source Projekte - TextFromSource (Findet Texte in *.pas Dateien,verschlüsseln)


X-Mailer - So 20.05.07 09:38
Titel: TextFromSource (Findet Texte in *.pas Dateien,verschlüsseln)
Programm von mir.

http://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 :

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 :


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 :


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.


GTA-Place - So 20.05.07 10:14

Nette Idee :zustimm:.


X-Mailer - So 20.05.07 11:26

Danke, ich habe das Programm schon für meine eigenen Projekte benutzt,
siehe RegRunner und X-Mailer Source
http://www.delphi-forum.de/topic_XMailer+70++++EMailprogramm+SMTP++POP3++nutzt+INDY_72941.html
http://www.delphi-forum.de/topic_RegRun2007++Ueberwacht+Registry+auf+Neueintraege_72940.html

Bei X-Mailer zur Übersetzung Deutsch / Englisch

Bei Regrunner zur besseren Übersicht aller enthaltenen Strings.

Gruss Bernd


Lannes - So 20.05.07 12:26

Hallo,

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


X-Mailer - 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 - 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...


Lannes - 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.


X-Mailer - So 20.05.07 15:03

Lannes, du bist der Beste... stimmt alles
Endlich einer der mich versteht :-)


HelgeLange - So 20.05.07 15:04

stimmt, die Zeile muss ich übersehen haben ;)


Calculon - 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 - 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 - 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 - So 20.05.07 21:27

Na also, geht doch :-)
Kannst ja auch meinen Source auf deine Anforderungen anpassen.