2 votes

Stockage et récupération de chaînes UTF-8 dans les fichiers de ressources Windows (RC)

J'ai créé un fichier RC qui contient une table de chaînes de caractères, j'aimerais utiliser des fonctions spéciales pour le traitement des données.

caractères : ö ü ó ú o u á é. Je sauvegarde donc la chaîne avec un encodage UTF-8.

Mais quand j'appelle dans mon fichier cpp, quelque chose comme ceci :

LoadString("hu.dll", 12, nn, MAX_PATH);

J'obtiens un résultat bizarre :

Error message with unexpected characters

Comment puis-je résoudre ce problème ?

8voto

Cody Gray Points 102261

Comme d'autres l'ont souligné dans les commentaires, les API Windows ne prennent pas directement en charge le texte codé en UTF-8. Vous ne pouvez pas passer l'option MessageBox et obtenez la sortie que vous attendez. Au lieu de cela, elle les interprétera comme des caractères de votre page de code locale.

Pour obtenir une chaîne UTF-8 à transmettre aux fonctions de l'API Windows (notamment MessageBox ), vous devez utiliser l'option MultiByteToWideChar pour convertir d'UTF-8 en UTF-16 (ce que Windows appelle Unicode, ou chaînes larges). En passant la fonction CP_UTF8 pour le premier paramètre est la magie qui permet cette conversion. Exemple :

std::wstring ConvertUTF8ToUTF16String(const char* pszUtf8String)
{
    // Determine the size required for the destination buffer.
    const int length = MultiByteToWideChar(CP_UTF8,
                                           0,   // no flags required
                                           pszUtf8String,
                                           -1,  // automatically determine length
                                           nullptr,
                                           0);

    // Allocate a buffer of the appropriate length.
    std::wstring utf16String(length, L'\0');

    // Call the function again to do the conversion.
    if (!MultiByteToWideChar(CP_UTF8,
                             0,
                             pszUtf8String,
                             -1,
                             &utf16String[0],
                             length))
    {
        // Uh-oh! Something went wrong.
        // Handle the failure condition, perhaps by throwing an exception.
        // Call the GetLastError() function for additional error information.
        throw std::runtime_error("The MultiByteToWideChar function failed");
    }

    // Return the converted UTF-16 string.
    return utf16String;                    
}

Ensuite, une fois que vous avez une chaîne large, vous appellerez explicitement la variante de la chaîne large de la fonction MessageBox fonction, MessageBoxW .

Toutefois, si vous devez uniquement prendre en charge Windows et non d'autres plates-formes qui utilisent UTF-8 partout, il vous sera probablement plus facile de vous en tenir exclusivement aux chaînes codées en UTF-16. Il s'agit de l'encodage Unicode natif utilisé par Windows, et vous pouvez transmettre ces types de chaînes directement à toutes les fonctions de l'API Windows. Voir ma réponse ici pour en savoir plus sur l'interaction entre les fonctions de l'API Windows et les chaînes de caractères. Je vous recommande la même chose qu'à l'autre :

  • S'en tenir à wchar_t y std::wstring pour vos caractères et chaînes de caractères, respectivement.
  • Appelez toujours le W des variantes des fonctions de l'API Windows, notamment LoadStringW y MessageBoxW .
  • Assurez-vous que le UNICODE y _UNICODE Les macros sont définies soit avant d'inclure les en-têtes Windows, soit dans les paramètres de construction de votre projet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X