Autor Beitrag
Ares
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 128



BeitragVerfasst: Mo 14.06.10 17:41 
Hallo!

Ich habe bislang viel mit Delphi gearbeitet. Für die Erstellung eines Programms in unterschiedlichen Sprachen habe ich dort immer mit String-Resourcen gearbeitet die per bedingter Compilierung in das Programm eingebunden wurden. Nun suche ich nach einer Möglichkeit dieses Prinzip auf C# zu übertragen.

Eine Resource-Datei sieht also z.B. so aus:
deutsche "Text_DE.txt"
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
STRINGTABLE
BEGIN
  1000, "OK"
  1001, "Abbrechen"
  1002, "Weiter"
  1003, "Zurück"
  1005, "Fertigstellen"
END


deutsche "Text_EN.txt"
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
STRINGTABLE
BEGIN
  1000, "OK"
  1001, "Cancel"
  1002, "Next"
  1003, "Back"
  1005, "Finish"
END


Dies wird dann mit BCC32 in eine RES-Dateien compiliert die in das Programm eingebunden werde.

ausblenden 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:
{$IFDEF langEN}
  {$R 'C:\Projekte\Texte\Texte_EN.RES'}
{$ELSE}
  {$R 'C:\Projekte\Texte\Texte_DE.RES'}
{$ENDIF}

...

function GetString(ID: Integer): String;
var
  p: PChar;
  loadResult: integer;
begin
  p := StrAlloc(1024);
  try
    loadResult := LoadString(hInstance, ID, p, 1023);
    if loadResult <> 0 then begin
      Result := p ;
  finally
    StrDispose(p);
  end;
end;

...

procedure ButtonClick(Sender: TObject);
begin
   ShowMessage(GetString(1000)); // Zeigt "OK" an...
end;



Nun Arbeite ich mit Visual Studio und C#. Lässt sich dieses Prinzip der Übersetzung hier auch nutzen?


Bei meinen bisherigen Nachforschungen bin ich nur auf die Möglichkeit gestoßen .RESX Dateien zu verwenden. Soweit ich das verstanden habe kann man diese aber nur in VS direkt im Projekt verwalten. Zudem ist das XML-Format dieser Dateien natürlich komplett anders als das der klassischen Resourcedateien.

Über die Zeit habe ich eine recht umfangreiche Sammlung von Standardtexten in fertigen Resourcedateien gesammelt. Diese würde ich natürlich gerne weiter verwenden, Lässt sich das oben beschriebene Prinzip also auch mit C# nutzen?

Eigentlich benötig ich 5 Dinge:
1. Erstellung von Texdateien
2. Übersetzung in Resource-Dateien
3. Bedingte Compilierung um je nach Sprache unterschiedliche Texte zu laden
4. Möglichkeit Resource-Dateien per Quelltext einzubinden
5. Möglichkeit auf enthaltene Resourcen per Quelltext zuzugreifen.

Für Schritt 1 und 2 könnte ich weiterhin einen Texteditor und BCC32 verwenden. Die Bedingte Complierung ist soweit ich gesehen habe in C# mit "#define xy=true", "#if xy" und "#endif" kein Problem.

Bleiben also noch die Schritte 3-4 für die ich bislang keine Lösung gefunden habe. Kennt jemand eine Lösung?

Besten Dank
Ares
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 14.06.10 17:49 
Hm, die Lokalisierung von Anwendungen in .NET läuft (bei WinForms) so: www.c-sharp-forum.de....php?p=455380#455380

Bedingte Kompilieren ist da eher unüblich :gruebel:

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Ares Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 128



BeitragVerfasst: Mo 14.06.10 18:02 
Hallo Christian,

vielen Dank für die schnelle Antwort! Ja, das das Resourcen nicht der übliche Weg sind C# Projekte zu lokalisieren habe ich auch schon rausgefunden :-) Wie gesagt habe ich nur Quellen darüber gefunden wie man die RESX-Dateien, etc. verwendet...

Sicherlich hat die "normale .NET Methode" für die Lokalisierung auch viele Vorteile. Bei mir wäre aber der riesengroße Nachteil, dass ich meine ganzen bestehenden Übersetzungen nicht mehr verwenden könnte. Bislang muss jeden Text nur einmal übersetzten und kann diesen dann in beliebigen Delphi-Programmen und Projekten verwenden.

Wenn ich das Ganze nun auf die .NET Methode umstelle wäre der Aufwand enorm hoch. Zudem will ich in Zukunft mit .NET und Delphi parallel arbeiten. Da wäre ein gemeinsames System der Übersetzung von sehr großem Vorteil...

Ist die "Delphi-Methode" also auf .NET übertragbar oder lässt sich diese hier gar nicht anwenden?
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Mo 14.06.10 18:17 
Was Du machen könntest, ist, Dir aus Deinen Text-Dateien die "normalen" resx-Dateien von .NET generiert. Ich habe gerade mal geschaut, Du musst da im Prinzip eine leere, von Visual Studio erzeugte resx-Datei nehmen und den von mir markierten Teil jeweils anhängen:
ausblenden volle Höhe XML-Daten
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:
<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <data name="Test" xml:space="preserve">
    <value>Testwert</value>
  </data>
  <data name="Test2" xml:space="preserve">
    <value>Testwert2</value>
  </data>
  <data name="Test3" xml:space="preserve">
    <value>Testwert3</value>
  </data>  
  <data name="Test4" xml:space="preserve">
    <value>Testwert4</value>
  </data>
    
</root>


Netterweise generiert Visual Studio dann daraus auch wieder die Klasse, um bequem auf die Eigenschaften zugreifen zu können. Über verschiedene Build-Konfigurationen in Visual Studio könntest Du dabei dann die resx-Datei jeweils aus einer anderen Sprache erzeugen.

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".