JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=63a81ca31509f28ff447468fe03b503bMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Unicode + wfstream + winapi

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 15.11.2008, 16:21    Titel: Unicode + wfstream + winapi Antworten mit Zitat

Hat jemand schon mal erfolgreich mit diesen Dingen gleichzeitig gearbeitet?

Es gibt da leider ziemlich bescheuerte Probleme.
So ließt wfstream wie ein normaler fstream nur ein Byte pro Zeichen. Das hier hab ich auch schon probiert, da wird allerdings gar nichts mehr ausgelesen.

Außerdem klappt die Darstellung eines Unicodezeichens nicht auf allen winapi-Elementen.
In Menüs und Tabcontrols klappt es, auf Buttons und statischem Text erscheinen dort nur Rechtecke.

Gibt es dafür Lösungen?
Ich kann mir kaum vorstellen, wofür man überhaupt Unicode verwenden soll, wenn weder Input noch Output damit funktioniert... Confused
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 15.11.2008, 17:20    Titel: Antworten mit Zitat

mmmhh also mit TEXT und so hab ich noch nie gearbeitet aber ich benutz file streams und unicode gleichzeitig + winapi.
Bei der Winapi gibts bis auf ein paar wenige Ausnahmen zu jeder Funktion eine W Variante die je nachdem wie du deinen Kompiler eingestellt hast standerdmäßig benutzt wird.
und zu den fstream
::std::basic_ifstream<wchar_t> Input
und
::std::basic_ofstream<wchar_t> Output
geht eigtl problemlos ...
wenn du willst kann ich mal meine Read und Write Funktionen posten sind kein so großes geheimnis^^

bzw zu deinem Problem mit dem Zeichensatz welchen Kompiler benutzt du?
Ich hatte sowohl mit VC++ 2005 Express und auch mit dem 2008 keine Probleme
_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 15.11.2008, 19:01    Titel: Antworten mit Zitat

fast hawk hat Folgendes geschrieben:
Bei der Winapi gibts bis auf ein paar wenige Ausnahmen zu jeder Funktion eine W Variante die je nachdem wie du deinen Kompiler eingestellt hast standerdmäßig benutzt wird.

Nuja...ich hab bei den Projekteinstellungen schon auf Unicode umgeschaltet und der Compiler schlägt von den verwendeten Funktionen auch entsprechend die W-Version vor. Trotzdem werden Zeichen außerhalb des ASCII-Satzes nur in Menüs und in Tabs dargestellt.

Als Beispiel hab ich mal dieses kyrillische Zeichen genommen: Д.
Kannst du das beispielsweise als statischen Text anzeigen lassen?

fast hawk hat Folgendes geschrieben:
wenn du willst kann ich mal meine Read und Write Funktionen posten sind kein so großes geheimnis^^

Ja, zeig mal bitte. Ich hab durch die Methode das Д nicht korrekt auslesen können.

Ich verwende VisualStudio 2005.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 19.11.2008, 20:27    Titel: Antworten mit Zitat

Code:

typedef bool lcgb;
typedef wchar_t lcgcw;
typedef ::std::basic_string<lcgcw> lcgsw;

Code:

std::vector<lcgsw > ReadFile(lcgsw FileName,lcgsw Spliter) //Lisst eine Datei aus
{
    lcgsw   buffer;  // Buffer bereitstellen
    std::basic_ifstream<lcgcw> input (FileName.c_str()); // Datei einlesen
   if (!input)
   {
      std::vector<lcgsw > Error;
      return Error;
   }
   std::vector<lcgsw > Ausgabe;
        // Solane eine Zeile einlesen bis keine mehr da ist.
    while(std::getline(input, buffer))
   {             
      // Wenn die Zeile leer ist überspringen
        if (buffer.empty ())
            continue;
       
            // Zeile Splitten nach 'Splitter'
      std::vector<lcgsw > split_string (splitString(buffer, Spliter));

      for(unsigned long i=0;i < split_string.size();i++)
      {       
         Ausgabe.push_back(split_string[i].c_str());
      }

    }

return Ausgabe;
}

Code:

lcgb WriteFile(lcgsw Text,lcgsw FileName)
{
std::basic_ofstream<wchar_t> out (FileName.c_str());
out << Text.c_str() << std::endl;
return true;
}

das sind die beiden Funktionen ich glaub zum größteil auch iwo geklaut und zusammengestückelt....
sry das ich so lang zum antworten gebraucht hab Sad

also test nr.1 war erfolgreich:
statisch als Text kann meiner(VC 2008) sie anzeigen jedoch muss er dafür die quellcode dateien (.cpp/.rc) in ein unicode format konvertieren.
vllt macht das der VC 2005 noch nicht.

test nr. 2
mmmhhh also alles programm interne geht unicode nur:
die streams können keine unicode textdateien lesen.....
hab grad vorhin auch mal gegoogelt so wirklich findet man nichts außer des irgendjmd von uifstream etc. schreibt aber des hab ich in meiner biblotheck nicht gefunden. ich werd mal gucken das interessiert mich jetzt um ehrlich zu sein auch... Smile

viele grüße
_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 19.11.2008, 20:50    Titel: Antworten mit Zitat

also ich hab ne naja bisschen geschummelte Möglichkeit gefunden
Unicode auszulesen. geht sicher noch feiner....
Code:

   char cbuffer[512];
   wchar_t wbuffer[256];
    lcgsw   buffer;  // Buffer bereitstellen
   ::std::ifstream input (L"d:\\text.txt",::std::ios::in | ::std::ios::binary); // Datei einlesen
   if (!input.is_open())
   {
      std::vector<lcgsw > Error;
      return Error;
   }
      ZeroMemory(cbuffer,512);
      input.read(cbuffer,512);
      ::memcpy(wbuffer,&cbuffer[2],510);
      buffer = wbuffer;

      Ausgabe.push_back(buffer);

_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 19.11.2008, 21:18    Titel: Antworten mit Zitat

nachtrag:
Code:

std::vector<lcgsw > ReadFile(lcgsw FileName,lcgsw Spliter) //Lisst eine Datei aus
{
   char* cbuffer;
   wchar_t* wbuffer;
   unsigned long count = 0;
    lcgsw   buffer;  // Buffer bereitstellen
   ::std::ifstream input (FileName.c_str(),::std::ios::in | ::std::ios::binary); // Datei einlesen
   if (!input.is_open())
   {
      std::vector<lcgsw > Error;
      return Error;
   }
   std::vector<lcgsw > Ausgabe;

   {
      input.seekg(0,::std::ios::end);
      count = input.tellg();count+=2;
      input.seekg(0);
      cbuffer = new char[count];
      wbuffer = new wchar_t[count/2-2];
      ZeroMemory(cbuffer,count);
      input.get(cbuffer,count);

      ::memcpy(wbuffer,&cbuffer[2],count-2);
      buffer = wbuffer;

           std::vector<lcgsw > split_string (splitString(buffer, Spliter));

      for(unsigned long i=0;i < split_string.size();i++)
      {       
         Ausgabe.push_back(split_string[i].c_str());
      }

    }

return Ausgabe;
}

_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 20.11.2008, 15:28    Titel: Antworten mit Zitat

ich glaub das ist jetzt erstmal mein letzter eintrag:
CPP:
#ifdef UNICODE
#define ReadTextFile ReadTextFileW
#else
#define ReadTextFile ReadTextFileA
#endif

CPP:
template<typename IC>
::std::basic_string<char> ReadTextFileA(::std::basic_string<IC> FileName)
{
   ::std::ifstream iStream (FileName.c_str(),::std::ios::in | ::std::ios::binary | ::std::ios::ate); // Datei einlesen
   if (!iStream.is_open()) { return ""; }
   
   unsigned long FileSize = 1+iStream.tellg(); iStream.seekg(0);
   char* tBuff = new char[FileSize]; ZeroMemory(tBuff,FileSize);
   wchar_t* wtBuff = 0;
   ::std::basic_string<char> result;

   iStream.read(tBuff,FileSize);
   
   if(tBuff[0] == (char)0xEF && tBuff[1] == (char)0xBB && tBuff[2] == (char)0xBF) { //UTF - 8
      result = &tBuff[3];
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFF && tBuff[1] == (char)0xFE) { //UTF - 16 little endian
      wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
      ::memcpy(wtBuff,&tBuff[2],FileSize-3);
      wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
      ::WideCharToMultiByte(CP_ACP,0,wtBuff,((FileSize-2)/sizeof(wchar_t)),tBuff,FileSize,0,0);
      result = tBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFE  && tBuff[1] == (char)0xFF) { //UTF - 16 big endian
      char tcBuffer = 0;
      for(unsigned int cChars=2;cChars<(FileSize-1);cChars+=2) {
         tcBuffer = tBuff[cChars];
         tBuff[cChars] = tBuff[cChars+1];
         tBuff[cChars+1] = tcBuffer; }

      wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
      ::memcpy(wtBuff,&tBuff[2],FileSize-3);
      wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
      ::WideCharToMultiByte(CP_ACP,0,wtBuff,((FileSize-2)/sizeof(wchar_t)),tBuff,FileSize,0,0);
      result = tBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFF  && tBuff[0] == (char)0xFE  && tBuff[2] == (char)0x00  && tBuff[3] == (char)0x00)return "not supported file typ(UTF-32LE)"; //UTF - 32 little endian
   else if(tBuff[0] == (char)0x00  && tBuff[1] == (char)0x00  && tBuff[2] == (char)0xFE  && tBuff[3] == (char)0xFF)return "not supported file typ(UTF-32BE)"; //UTF - 32 big endian
   else { //ASCII
      result = tBuff;
      delete[] tBuff;
   return result;
   }
return "";
}


template<typename IC>
::std::basic_string<wchar_t> ReadTextFileW(::std::basic_string<IC> FileName)
{
   ::std::ifstream iStream (FileName.c_str(),::std::ios::in | ::std::ios::binary | ::std::ios::ate); // Datei einlesen
   if (!iStream.is_open()) { return L""; }
   
   unsigned long FileSize = 1+iStream.tellg(); iStream.seekg(0);
   char* tBuff = new char[FileSize]; ZeroMemory(tBuff,FileSize);
   wchar_t* wtBuff = 0;
   ::std::basic_string<wchar_t> result;

   iStream.read(tBuff,FileSize);
   
   if(tBuff[0] == (char)0xEF && tBuff[1] == (char)0xBB && tBuff[2] == (char)0xBF) { //UTF - 8
      wtBuff = new wchar_t[FileSize-3];
      ::MultiByteToWideChar(CP_ACP,0,&tBuff[3],(FileSize-3),wtBuff,(FileSize-3));
      result = wtBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFF && tBuff[1] == (char)0xFE) { //UTF - 16 little endian
      wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
      ::memcpy(wtBuff,&tBuff[2],FileSize-3);
      wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
      result = wtBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFE  && tBuff[1] == (char)0xFF) { //UTF - 16 big endian
      char tcBuffer = 0;
      for(unsigned int cChars=2;cChars<(FileSize-1);cChars+=2) {
         tcBuffer = tBuff[cChars];
         tBuff[cChars] = tBuff[cChars+1];
         tBuff[cChars+1] = tcBuffer; }

      wtBuff = new wchar_t[((FileSize-1)/sizeof(wchar_t))];
      ::memcpy(wtBuff,&tBuff[2],FileSize-3);
      wtBuff[((FileSize-1)/sizeof(wchar_t))-1] = '\0';
      result = wtBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
   else if(tBuff[0] == (char)0xFF  && tBuff[0] == (char)0xFE  && tBuff[2] == (char)0x00  && tBuff[3] == (char)0x00)return L"not supported file typ(UTF-32LE)"; //UTF - 32 little endian
   else if(tBuff[0] == (char)0x00  && tBuff[1] == (char)0x00  && tBuff[2] == (char)0xFE  && tBuff[3] == (char)0xFF)return L"not supported file typ(UTF-32BE)"; //UTF - 32 big endian
   else { //ASCII
      wtBuff = new wchar_t[FileSize];
      ::MultiByteToWideChar(CP_ACP,0,tBuff,FileSize,wtBuff,FileSize);
      result = wtBuff;
      delete[] wtBuff;
      delete[] tBuff;
   return result;
   }
return L"";
}


zwei Funktionen die den Text aus jedem Format das Notepad erstellen kann ausliehst. einmal mit einem char Rückgabewert und einmal mit einem wchar_t Rückgabewert. UTF-32 eigtl. imo noch nicht unterstüzt es gibt auch noch keinen wchar_t mit 4 bytes (soweit ich weiß)
Rückmeldung ist erwünscht *g*

Test:
Zitat:

Ausgabe in Unicode(2Bytes)
Dateigröße: 6,772 Bytes
3.0 GHz(2x) bei 7200u/m
1mil(UTF-16BE):97.83 Sek
1mil(ANSII):81.15 Sek
1mil(UTF-16LE):77.47 Sek
1mil(UTF-Cool:78.39 Sek


viele grüße
Lukas
_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann


Zuletzt bearbeitet von fast hawk am 20.11.2008, 18:34, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 20.11.2008, 17:53    Titel: Antworten mit Zitat

fast hawk: versuch ma bitte die edit- und die c++-funktionen zu benutzen, sich so dadurchzulesen tut ein bisschen in den Augen weh Razz also cpp statt code-tag.

TLOP: wieso funktioniert die Methode mit dem codecvt-objekt nicht? das ist meiner meinung nach die effektivste (und auch dafür entwickelte) Methode, vor allem weil du in der STL bleibst und nichts zusammenmischst. Poste am besten mal deine Implementierung (also den Code) wie du std::codecvt benutzt, besser mehr als wenig =)

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 20.11.2008, 19:14    Titel: Antworten mit Zitat

Cool, danke für deine Mühe Smile

Ich teste es.

fast hawk hat Folgendes geschrieben:
also test nr.1 war erfolgreich:
statisch als Text kann meiner(VC 2008) sie anzeigen jedoch muss er dafür die quellcode dateien (.cpp/.rc) in ein unicode format konvertieren.
vllt macht das der VC 2005 noch nicht.

Wenn ich ein exotisches Zeichen im Quellcode ablege, fragt VS2005 das auch und wandelt die Quellcodedatei in Unicode um. Hab das gleiche mit der RC-Datei gemacht, aber es gibt keine Besserung.
Hast du alle Quellcodedateien umwandeln müssen? Hat VS das automatisch gemacht oder gibts da ne Option?



@DirectXer:
Hab noch mal kontrolliert.
Hatte die Datei nicht im binären Modus geöffnet. Auslesen funktioniert nun =)

Kleiner Schönheitsfehler ist, dass man getline nicht mehr anständig verwenden kann, da der Zeilenumbruch nicht nur von einem Zeichen(\n), sondern zwei dargestellt wird(\r\n). Muss also das eine Zeichen nach std::getline() noch abtrennen und auch das erste Zeichen, das er überhaupt liest.

Darstellung auf winapi-Controls ist nun immer noch das Problem.
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
The Lord of Programming
Living Legend


Alter: 37
Anmeldedatum: 14.03.2003
Beiträge: 3122

Medaillen: Keine

BeitragVerfasst am: 29.11.2008, 15:57    Titel: Antworten mit Zitat

Also, es liegt am Font.

Beim Ressourceneditor in VS war MS Sans Serif eingestellt, was diese Zeichen offenbar gar nicht kennt. Tahoma beispielsweise funktioniert.

Was mich noch interessiert, fast hawk, welchen Font hattest du eingestellt und auf welchem Betriebssystem hast du es getestet?
_________________
www.visualgamesentertainment.net
Current projects: RDTDC(1), JLI-Vor-Projekt, Tetris(-Tutorial), JLI-Format
(1) Realtime Developer Testing and Debugging Console


Anschlag, Anleitung zum Atombombenbau, Sprengkörper...
Hilf Schäuble! Damit er auch was findet...
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Entwicklung Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum