Arabische Zeichen in TEdit von der App setzen



  • Morgähn,

    mal ne Frage: Wie kann ich aus der App heraus z. B. arabische Schriftzeichen in ein TEdit setzen?
    So funktioniert es jedenfalls nicht:

    LoadKeyboardLayout( "00000401", KLF_ACTIVATE );             	// arabisch( Saudi Arabia )
    InputEdit->BiDiMode = bdRightToLeft;
    InputEdit->Font->Name = "Arial Unicode MS";
    InputEdit->Font->Charset = ARABIC_CHARSET;
    InputEdit->Text = "وقف";  // <- soll arabischer Text sein. Aber egal was hier kommt, nix funktioniert :(
    

    Im Edit steht danach nur Müll( der Text oben ist nur zum testen )
    Wenn ich in das Edit etwas über Tastatur eingebe, kommt arabischer Text. Soweit ich das jedenfalls beurteilen kann 🙄

    Hab ich was vergessen? Sonstwas falsch gemacht? 😕 😕 😕

    grüssle 🙂



  • Die VCL ist erst ab dem BCB 2009 Unicodefähig, d.h. du kannst momentan weder Russisch noch Arabisch richtig anzeigen. Allerdings gibt es Komponenten, die das können im Internet: schau mal hier. Oder du programmierst dir eigene Komponenten.



  • Linnea schrieb:

    Die VCL ist erst ab dem BCB 2009 Unicodefähig, d.h. du kannst momentan weder Russisch noch Arabisch richtig anzeigen. Allerdings gibt es Komponenten, die das können im Internet: schau mal hier. Oder du programmierst dir eigene Komponenten.

    Stimmt, im BCB2009 gibts dafür den UnicodeString. Den verwende ich auch 🙂
    Habs jetzt raus. Der Fehler liegt beim speichern der Texte im TList. Also noch ne cast Orgie, dann sollte es passen.

    Thx & grüssle 🙂



  • Wenn du statt der TList einen der Standardcontainer nehmen würdest (wie schon vorgeschlagen) wäre dir die Cast-Orgie erspart geblieben.



  • Braunstein schrieb:

    Wenn du statt der TList einen der Standardcontainer nehmen würdest (wie schon vorgeschlagen) wäre dir die Cast-Orgie erspart geblieben.

    Dummerweise hab ich das Projekt so übernommen. Die Änderung TList -> Standardcontainer wäre wahrscheinlich zeitaufwändiger.
    Aber wenn ich nochmal - mit einem neuen Projekt - in diese Situation komme, werde ich deinen Ratschlag beherzigen.

    grüssle 🙂



  • Hallo,
    mit TList hat es nichts zu tun, Du musst auch nicht casten. Du musst vor die Zeichenkette im Quelltext das Literal "u" schreiben.

    TEdit1->Text = u"ليبثفثفس";
    TEdit2->Text = u"δδφφτες";
    TEdit3->Text = u"ьщылфгрввр";

    Das ganze mit dem Tastaturlayout kannst Du Dir sparen. Du musst in Windiws die Zeichensätze laden und kannst sie dann auch ganz einfach umschalten.

    Wenn Du C++ Container und Zeichenketten verwendest, darfst Du nicht string nehmen, sondern wstring.

    Schöne Grüße

    Volker



  • VolkerH schrieb:

    Wenn Du C++ Container und Zeichenketten verwendest, darfst Du nicht string nehmen, sondern wstring.

    Kommt drauf an. Für UTF-8 taugt std::string genauso wie std::wstring für UTF-16.



  • Hallo,
    das stimmt leider nicht. Mit einem string kann man eigentlich grundsätzlich nur ASCII- Zeichen speichern, dazu ist er da. Und mit den wchar_t- Typ ist es kompliziert, der ist compilerabhängig. Wenn man also Unicode in C++ speichern will, muss man schon etwas aufpassen.

    Hier im Foum wurde schon einmal ein Link gepostet, zu dem Thema.
    http://www.kharchi.eu/wiki/doku.php?id=cpp:std:string#zeichencodeumwandlung_ascii_ucs_und_unicode

    Einfach mal lesen. Der Autor hat sich viel Mühe gegeben.

    Schöne Grüße

    Volker



  • VolkerH schrieb:

    das stimmt leider nicht. Mit einem string kann man eigentlich grundsätzlich nur ASCII- Zeichen speichern, dazu ist er da.

    ?

    In einem String kannst du alles speichern, was du willst. Wären Strings auf ASCII-Zeichen limitiert, dann könntest du kein Zeichen >= 128, mithin keine Umlaute oder Sonderzeichen benutzen. Und das wäre mir neu 😉

    Ebenso kannst du in einem std::string einen UTF-8-codierten String unterbringen (char ist mindestens ein Byte groß), oder einen UTF-16-String in einem std::wstring. Das setzt natürlich voraus, daß die Funktionen, denen du deine Strings übergibst, auch mit einem entsprechend codierten String rechnen; unter Windows wäre z.B. für einen UTF-8-String eine Konvertierung notwendig. Da Windows 2000 und neuer UTF-16 verwenden, könntest du aber UTF-16-codierte Strings direkt an Windows-Funktionen weitergeben.

    VolkerH schrieb:

    Und mit den wchar_t- Typ ist es kompliziert, der ist compilerabhängig.

    Falls du dich auf die Aussage des Artikels, daß wchar_t unter den meisten Windows-Compilern 16 Bit groß sei, beim GCC aber 32 Bit, beziehst: das gilt gleichfalls für char. Soweit ich weiß, steht nirgendwo geschrieben, daß char nur ein Byte groß sein dürfe.

    VolkerH schrieb:

    Wenn man also Unicode in C++ speichern will, muss man schon etwas aufpassen.

    Dem kann ich uneingeschränkt zustimmen 😉

    VolkerH schrieb:

    Hier im Foum wurde schon einmal ein Link gepostet, zu dem Thema.
    http://www.kharchi.eu/wiki/doku.php?id=cpp:std:string#zeichencodeumwandlung_ascii_ucs_und_unicode

    Einfach mal lesen. Der Autor hat sich viel Mühe gegeben.

    Besten Dank, kenne ich schon 😉
    Artchi hat sich sicherlich Mühe gegeben, aber das macht seinen Artikel nicht fehlerlos. Beispielsweise behauptet er, Windows NT ab 4.0 arbeite mit UCS2; seit Windows 2000 ist es aber UTF-16.



  • Hallo,
    Du kannst in einem string sicher auch Bilder speichern, nur kannst Du damit dann relativ wenig anfangen. Die grundlegende Speichereinheit im Rechner ist ja noch das Byte. Insofern hast Du recht, aber doch das Thema verfehlt.

    Denn mit dem Bgriff "Verwendung" ist sicher nicht nur die Möglichkeit gemeint, die Informationen zu hinterlegen, sondern mit den entsprechenden Funktionen mit den Daten zu arbeiten. Und da fängt auch das UTF8- Problem an, hier werden variable Längen verwendet, die der string zwar speichern kann, aber mit der die string- Klasse dann meines Wissens nichts anfangen kann.´Aber ich gebe es ehrlich zu, ich bin bzgl. UTF sicher kein Experte, ich kann mich da nur auf Hörensagen verlassen, auf einen normalen Verstand wie Compiler mit Datenfeldern umgehen und auf meine eigenen Erfahrungen mit der Stringklasse.

    Und das char- Zeichen ist klar definiert. Das die meisten Compiler Variablen im Speicher ausrichten, und damit für ein Byte oft 3 verschenken, hat damit nichts zu tun. Interessant wäre da nur das Feld von 4 Zeichen, und die Frage ab das dann auch 4 * 4 Byte lang ist.

    Daher hast Du auch mit dem ASCII- Code recht. Dank dem "unsigned" kann ich in einem Zeichen 256 verschiedene Zeichen darstellen, der ASCII- Code ist ursprünglich nur 7 Bit codiert, kann also nur 128 Zeichen darstellen. Ich bin da einfach zu oberflächlich, ich bezeichne wie viele meienr Kollegen den erweiterten ASCII- Zeichensatz, mit dem wir uns viele Jahre herumgeschlagen habe, der Einfachheit halber auch nur als ASCII.

    Aber im Grunde sind wir uns einig, es ist nicht so einfach. Und wie Du es ja zu dem Autor des von mir zitierten Artikels schriebst, wir machen alle Fehler und sind weit davon entfernt, unfehlbar zu sein. leider vergessen das einige zu gern.

    Nimm es mir nicht übel. Die Art der Profilierung, die aus Deinem Posting spricht, ist ein Grund, warum ich in Programmierforen relativ wenig schreibe. Aber vielleicht bin ich da auch nur im Laufe der Jahre etwas empfindlich geworden.

    Schöne Grüße aus Berlin

    Volker



  • VolkerH schrieb:

    Und das char- Zeichen ist klar definiert.

    Der Standard sagt nur etwas über die minimale Größe. So klar ist das also nicht.
    Standard 3.9.1 1

    Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character set...



  • VolkerH schrieb:

    Denn mit dem Bgriff "Verwendung" ist sicher nicht nur die Möglichkeit gemeint, die Informationen zu hinterlegen, sondern mit den entsprechenden Funktionen mit den Daten zu arbeiten. Und da fängt auch das UTF8- Problem an, hier werden variable Längen verwendet, die der string zwar speichern kann, aber mit der die string- Klasse dann meines Wissens nichts anfangen kann.

    Nicht nur UTF-8, auch UTF-16 unterstützt Zeichen variabler Länge, dementsprechend hast du dasselbe Problem bei std::wstring. (Weiteres unten.)

    VolkerH schrieb:

    Und das char- Zeichen ist klar definiert. Das die meisten Compiler Variablen im Speicher ausrichten, und damit für ein Byte oft 3 verschenken, hat damit nichts zu tun. Interessant wäre da nur das Feld von 4 Zeichen, und die Frage ab das dann auch 4 * 4 Byte lang ist.

    Dazu hat Braunstein bereits näher erläutert, was ich sagen wollte. Theoretisch kannst du durchaus einer standardkonformen C++-Implementation begegnen, die zwei Bytes oder gar mehr pro char verwendet.

    VolkerH schrieb:

    Und wie Du es ja zu dem Autor des von mir zitierten Artikels schriebst, wir machen alle Fehler und sind weit davon entfernt, unfehlbar zu sein. leider vergessen das einige zu gern.

    Danke für den dezenten Hinweis 😉 Wenn mir ein Fehler unterläuft, lasse ich mich gerne darauf hinweisen.

    VolkerH schrieb:

    Nimm es mir nicht übel. Die Art der Profilierung, die aus Deinem Posting spricht, ist ein Grund, warum ich in Programmierforen relativ wenig schreibe.

    Daß du mein Posting so auffaßt, bedaure ich. Falls du die Sache mit ASCII und char als Besserwisserei deutest, so muß ich mich deutlicher erklären:

    std::string und std::wstring sind eigentlich nichts weiter als etwas komfortabler benutzbare Varianten von std::vector <char> und std::vector <wchar_t>. Die String-Klassen enthalten keine Funktionalität, für die der tatsächliche Inhalt, die Interpretation der enthaltenen Daten, von Bedeutung wäre; es wird lediglich verlangt, daß der Inhalt, jedenfalls beim Gebrauch der Komfortfunktionen wie operator +, c_str() etc., nullterminiert ist.

    Insofern ist es in den meisten Fällen völlig unerheblich, ob zwei Zeichen, die du separat betrachtest, tatsächlich ein einziges darstellen, solange du sie nicht interpretierst. Kritisch wird es also erst bei Code, der den String abhängig vom Inhalt verarbeitet, z.B. eine Funktion, die einen Dateipfad in die Einzelteile (Laufwerk, Verzeichnis, Datei, Endung) zerlegt. Angenehmerweise funktioniert derartiger Code gewöhnlich auch für UTF-8- oder UTF-16-codierte Strings, da beide Encodings ASCII-kompatibel sind. Auch wenn du einen UTF-8-String beispielsweise rückwärts parst, kannst du sicher sein, daß jedes Zeichen < 128 nicht der n-te Teil eines Multibyte/Multiword-Zeichens ist, sondern ein einzelnes ASCII-Zeichen.

    Erst wenn es wichtig wird, einzelne Buchstaben als solche zu isolieren, zu interpretieren, oder z.B. die Anzahl der darzustellenden Zeichen zu erfahren (std::string::size() und std::wstring::size() geben genauso wie UnicodeString::Length () die Anzahl der Bytes bzw. Words zurück, nicht die Anzahl der Buchstaben!), mußt du UTF-8- oder UTF-16-codierte Strings gesondert behandeln, z.B. mit Betriebssystemfunktionen.

    Daß mein Antwortposting nicht Freundlichkeit bis zum Anschlag vermittelte, kann auch an der Attitüde liegen, die ich aus deinem vorhergehenden Post las:

    VolkerH schrieb:

    das stimmt leider nicht. Mit einem string kann man eigentlich grundsätzlich nur ASCII- Zeichen speichern, dazu ist er da. Und mit den wchar_t- Typ ist es kompliziert, der ist compilerabhängig.

    Damit implizierst du eher, daß du es wüßtest, und nicht, daß es deine durch "Hörensagen [...], einen normalen Verstand wie Compiler mit Datenfeldern umgehen und auf meine eigenen Erfahrungen mit der Stringklasse" geprägten Erfahrungen wären. Da ich mich meiner Auffassungen ähnlich sicher glaubte, widersprach ich.

    Auch das hier

    VolkerH schrieb:

    Hier im Foum wurde schon einmal ein Link gepostet, zu dem Thema.
    [...]
    Einfach mal lesen. Der Autor hat sich viel Mühe gegeben.

    klang, als hätte ich einfach nur eine aus Unwissen entstandende Behauptung in den Raum gestellt. Wenn ich aber ein so diametrales Statement wie

    audacia schrieb:

    Kommt drauf an. Für UTF-8 taugt std::string genauso wie std::wstring für UTF-16.

    poste, kannst du davon ausgehen, daß ich über das Grundwissen und über Argumente für meine Aussage verfüge 😉



  • Hallo audacia,
    der Streit ist für die meisten, die hier lesen, so nützlich wie .... Na lassen wir das. Wir können das Niveau gerne anheben, aber warum? Das würde ich eher in einer Kneipe machen, als in einem Forum. Oder eben an einem Konferenztisch. Und wenn ich auch schon lange aufgehört habe, Standards wortwörtlich zu lesen (eigentlich seit dem Studium nicht mehr), solltest Du Dich von Aussagen wie "hörensagen" sicher nicht täuschen lassen. So habe ich mal "gehört", dass das char- Zeichen in C++ und C nicht gleich definiert ist, wenn Du C also als Untermenge von C++ siehst, muss es ein Byte sein. Da es in C genau ein Byte ist, in C++ aber mindestens ein Byte, naja, ich bin halt Mathematiker, da gibt es tatsächlich eine Schnittmenge.

    Dein Vergleich mit vector und string ist schon putzig, natürlich kann man es so sehen. Aber irgendwie klingt es bei Dir fast negativ. Der string ist ein normaler STL- Container, wie der vector auch. Aber man hat eine eigene "Vectorklasse" mit dem basic_string geschaffen. Da haben die Gurus, die die STL entworfen haben, sicher etwas übersehen ;-). Das es ein normaler STL- Container ist, für mich ist das gerade der Vorteil, kein Nachteil. Dazu kommt aber eben doch ein kleines bisschen mehr. Und die Zuweisungsoperatoren für normale Zeichenketten und die c_str- Funktion machen für mehr als 80% der Entwickler das Leben mit dieser Klasse doch einfacher (natürlich auch die Vergleichsoperatoren, die + Operatoren, nicht zu vergessen ach die << und >> operatoren für die Ein- und Ausgabe, ...). Die Mehrheit der Programmierer würde auch nicht auf die Idee kommen, etwas anderes damit zu machen, als Zeichenketten mit eben den genannten Funktionen zu verwalten. Dabei fängt Dank der STL der Spass ja erst an, da sind wir uns einig, und wenn ich dann höre, es gebe zum Beispiel keine trim- Funktion, stellen sich bei mir die Nackenhaare hoch.

    Wozu der Streit? Wir sind uns im Grunde genommen doch einig. Bezogen auf Unicode ist die Unterstützung für die C++ Strings eher rudimentär, und die variable Länge muss irgendwie aufgefangen werden.

    Aber es war eine praktische Frage, die zu dieser Diskussion führte, und mit der Antwort sollten die Leser doch auch etwas anfangen können. Um beim Builder zu bleiben, wenn Du einen UTF8 Code in einen string schaufelst, und via c_str() wieder herausholst, stehen nur noch Fragezeichen da. Schaufelst Du ihn hingegen in einen wstring (da wir hier ja beim Builder- Thema sind, da gibt es für die Delphi- UTF- Klasse extra die Funktion w_str()), und dann via c_str wieder zurück in den UTF- String, bleibt der Text erhalten. Zumindest in der Regel. Mmmhhhh, habe ich eben noch mal ausprobiert.

    Da ändert auch unsere ganze Diskussion nichts dran. Und glaub mir, ich bin C++ Fanatiker und mag solche Diskussionen, nur gehören sie nicht hier her. Damit können wir Interessenten nur abschrecken, die dann doch lieber C#, Java oder Delphi programmieren. Du kannst der Maße (ich denke mehr als 80%) der C++ Entwickler gerne erklären, dass sie, wenn sie ein bisschen drumherum machen und programmieren, das ganze trotzdem in strings speichern könnten. Es interessiert die meisten nicht.

    Schöne Grüße aus Berlin

    Volker



  • VolkerH schrieb:

    Dein Vergleich mit vector und string ist schon putzig, natürlich kann man es so sehen. Aber irgendwie klingt es bei Dir fast negativ.

    Ist aber nicht so gemeint; das war eine nüchterne Feststellung. Ich begrüße die Existenz von std::string anstelle z.B. einer Spezialisierung wie std::vector<bool>, und die vorhandenen Komfortfunktionen sind IMHO knapp am Mindesten dessen, was eine Stringklasse bieten sollte. (Auch hier Einigkeit!) Ich weiß nicht, wo du bei dem Vergleich mit std::vector eine Herablassung gegen die STL-Designer herausliest, aber meine Absicht war so etwas jedenfalls nicht.

    VolkerH schrieb:

    Die Mehrheit der Programmierer würde auch nicht auf die Idee kommen, etwas anderes damit zu machen, als Zeichenketten mit eben den genannten Funktionen zu verwalten.

    Klar. Und da std::[w]string so entworfen ist, daß es den Inhalt des Strings nicht weiter als bis zum terminierenden Nullzeichen interpretiert, kann man nützlicherweise beliebige Encodings darin unterbringen, solange man sich des jeweiligen Encodings bewußt bleibt.

    VolkerH schrieb:

    Bezogen auf Unicode ist die Unterstützung für die C++ Strings eher rudimentär, und die variable Länge muss irgendwie aufgefangen werden.

    Das ist, wie gesagt, situationsabhängig - und der meiste stringverarbeitende Code kommt mit UTF-8 bzw. UTF-16 zurecht. Punkt meines Statements war, daß du mit std::wstring für UTF-16 kein bißchen besser dran bist als mit std::string für UTF-8.
    (Was natürlich nichts daran ändert, daß die String-Typen in Delphi und C++Builder diese Aufgabe um Längen besser bewältigen.)

    VolkerH schrieb:

    Um beim Builder zu bleiben, wenn Du einen UTF8 Code in einen string schaufelst, und via c_str() wieder herausholst, stehen nur noch Fragezeichen da.

    UnicodeString::UnicodeString(const char*) nimmt an, es erhalte einen String mit der Codepage 0 (der System-Codepage). Wie könnte der Konstruktor wissen, welche Codepage der String tatsächlich hat? Wenn du die Codepage bei der Umwandlung von STL-String nach VCL-String explizit angibst, geht es wunderbar:

    std::string stl_string = "Heiz%F6lr%FCcksto%DFabd%E4mpfung";
    
      // entweder sagen wir direkt, daß dies ein UTF-8-String ist...
    String delphi_string = UTF8String (stl_string.c_str ());
    
      // ... oder wir arbeiten einfach auch auf VCL-Seite mit einem UTF-8-String.
    UTF8String utf8_string = stl_string.c_str ();
    

    VolkerH schrieb:

    Schaufelst Du ihn hingegen in einen wstring (da wir hier ja beim Builder- Thema sind, da gibt es für die Delphi- UTF- Klasse extra die Funktion w_str()), und dann via c_str wieder zurück in den UTF- String, bleibt der Text erhalten. Zumindest in der Regel.

    Das liegt daran, daß die hierzulande gebräuchlichen Zeichen alle in UCS-2, also in den statischen 2-Byte-Zeichensatz passen. Anstelle sich damit zu begnügen, sollte man sich eher der Urheber von 7-Bit-ASCII erinnern, die Sparsamkeit und Praktikabilität höher bewerteten als das Bedürftnis von Nichtanglophonen nach Umlauten oder Akzenten. (Das ärgert mich bei jeder MD, die ich betitle, erneut.) Frage mal einen Chinesen oder sonst jemanden, dessen Schriftzeichen nicht alle in UCS-2 gepaßt haben.

    VolkerH schrieb:

    Du kannst der Maße (ich denke mehr als 80%) der C++ Entwickler gerne erklären, dass sie, wenn sie ein bisschen drumherum machen und programmieren, das ganze trotzdem in strings speichern könnten. Es interessiert die meisten nicht.

    Wie du meinst.
    Was tut aber der nicht wechselwillige C++-Programmierer, der UTF-8 und UTF-16 benutzen muß, wenn nicht die Strings verwenden oder auf C++0x warten?


Anmelden zum Antworten