Comment faire pour convertir d'ANSI en Unicode et Unicode en ANSI pour OLE

Traductions disponibles Traductions disponibles
Numéro d'article: 138813 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Résumé

Toutes les chaînes qui sont transmises à et reçus d'OLE API 32 bits et de méthodes d'interface utilisent Unicode. Cela nécessite des applications qui utilisent des chaînes ANSI pour les convertir au format Unicode avant de les transmettre à OLE et pour convertir les chaînes Unicode qui sont reçues à partir d'OLE au format ANSI. Cet article explique comment ces conversions peuvent être effectuées.

Plus d'informations

Windows NT implémente Unicode (ou à caractère élargi) et les versions ANSI de fonctions Win32 qui acceptent des paramètres de chaîne. Cependant Windows 95 n'implémente pas la version Unicode de la plupart des fonctions Win32 qui prennent les paramètres de chaîne. Au lieu de cela, il implémente uniquement les versions ANSI de ces fonctions.

Une exception majeure à cette règle est 32 bits OLE. OLE API 32 bits et les méthodes d'interface sur Windows NT et Windows 95 utilisent exclusivement Unicode. Versions ANSI de ces fonctions ne sont pas implémentées sur Windows NT ou Windows 95.

Cela signifie qu'une application 32 bits qui doit s'exécuter sur Windows 95 et Windows NT doit utiliser les versions ANSI des fonctions non-OLE Win32 et doit convertir les chaînes ANSI en Unicode avant qu'ils sont passés à OLE.

Une application Unicode 32 bits qui s'exécute uniquement sous Windows NT n'avez donc pas besoin d'utiliser des fonctions de conversion Unicode/ANSI.

Win32 fournit MultiByteToWideChar et WideCharToMultiByte pour convertir des chaînes ANSI en Unicode et les chaînes Unicode en ANSI. Cet article fournit AnsiToUnicode et Unicode, qui utilise ces fonctions de conversion Unicode/ANSI.
/*
 * AnsiToUnicode converts the ANSI string pszA to a Unicode string
 * and returns the Unicode string through ppszW. Space for the
 * the converted string is allocated by AnsiToUnicode.
 */ 

HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{

    ULONG cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (NULL == pszA)
    {
        *ppszW = NULL;
        return NOERROR;
    }

    // Determine number of wide characters to be allocated for the
    // Unicode string.
    cCharacters =  strlen(pszA)+1;

    // Use of the OLE allocator is required if the resultant Unicode
    // string will be passed to another COM component and if that
    // component will free it. Otherwise you can use your own allocator.
    *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
    if (NULL == *ppszW)
        return E_OUTOFMEMORY;

    // Covert to Unicode.
    if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters,
                  *ppszW, cCharacters))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszW);
        *ppszW = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }

    return NOERROR;
/*
 * UnicodeToAnsi converts the Unicode string pszW to an ANSI string
 * and returns the ANSI string through ppszA. Space for the
 * the converted string is allocated by UnicodeToAnsi.
 */ 

HRESULT __fastcall UnicodeToAnsi(LPCOLESTR pszW, LPSTR* ppszA)
{

    ULONG cbAnsi, cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (pszW == NULL)
    {
        *ppszA = NULL;
        return NOERROR;
    }

    cCharacters = wcslen(pszW)+1;
    // Determine number of bytes to be allocated for ANSI string. An
    // ANSI string can have at most 2 bytes per character (for Double
    // Byte Character Strings.)
    cbAnsi = cCharacters*2;

    // Use of the OLE allocator is not required because the resultant
    // ANSI  string will never be passed to another COM component. You
    // can use your own allocator.
    *ppszA = (LPSTR) CoTaskMemAlloc(cbAnsi);
    if (NULL == *ppszA)
        return E_OUTOFMEMORY;

    // Convert to ANSI.
    if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, *ppszA,
                  cbAnsi, NULL, NULL))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszA);
        *ppszA = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }
    return NOERROR;

}
				
Exemple Utilisation de ces fonctions est la suivante. CoTaskMemFree est utilisée pour libérer la chaîne convertie si CoTaskMemAlloc a été utilisé pour allouer de la chaîne. La chaîne convertie ne doit pas être libérée si elle est renvoyée par l'intermédiaire d'un paramètre de sortie à un autre composant OLE, car ce composant est responsable de la libération de la chaîne. LPOLESTR est un pointeur vers une chaîne Unicode.
// The following code gets an ANSI filename that is specified by the
// user in the OpenFile common dialog. This file name is converted into
// a Unicode string and is passed to the OLE API CreateFileMoniker. The
// Unicode string is then freed.

OPENFILENAME ofn;
LPOLESTR pszFileNameW;
LPMONIKER pmk;
:

// Get file name from OpenFile Common Dialog. The ANSI file name will
// be placed in ofn.lpstrFile

GetOpenFileName(&ofn);
:
AnsiToUnicode(ofn.lpstrFile, &pszFileNameW);
CreateFileMoniker(pszFileNameW, &pmk);
CoTaskMemFree(pszFileNameW);

// The following code implements IOleInPlaceFrame::SetStatusText.
// The lpszStatusText string, that is received from another OLE
// component, uses Unicode. The string is converted to ANSI before it is
// passed to the ANSI version of SetWindowText. Windows 95 supports only
// the ANSI version of SetWindowText.

COleInPlaceFrame::SetStatusText(LPCOLESTR pszStatusTextW)
{

    LPSTR pszStatusTextA;
    UnicodeToAnsi(pszStatusTextW, &pszStatusTextA);
    SetWindowText(m_hwndStatus, pszStatusTextA);
    CoTaskMemFree(pszStatusTextA);

}
				
Remarque : commentaires dans AnsiToUnicode et UnicodeToAnsi concernant l'allocateur est utilisée pour allouer de la chaîne convertie. CoTaskMemAlloc (l'allocateur OLE) est requis pour être utilisé uniquement si la chaîne résultante sera passée à un autre composant OLE et si ce composant peut libérer la chaîne. Cela signifie que les chaînes est passées en tant que dans paramètres aux méthodes d'interface OLE n'avez donc pas besoin d'utiliser l'allocateur OLE. Les chaînes qui sont transmis en tant qu'out-paramètres ou renvoyés par le biais de paramètres out ou hors-paramètres doivent être alloués à l'aide de l'allocateur OLE.

Constantes de chaîne peuvent être convertis au format Unicode au moment de la compilation à l'aide de la macro OLESTR. Par exemple :
CreateFileMoniker(OLESTR("c:\\boo\\har.doc"), &pmk);
				
un autre exemple de routines de conversion Unicode/ANSI peut être trouvé dans le code de source MFC (Microsoft Foundation Classes) qui est livré avec le compilateur Visual C++ 4.0. Ces routines sont décrites dans la note technique MFC 59: 'Utilisation des macros MFC MBCS/Unicode conversion'. La définition de ces macros OLE2T, T2OLE, OLE2CT, T2COLE, A2W, W2A, A2CW, W2CA et USES_CONVERSION sont dans \msdev\mfc\include\afxpriv.h. Consultez également AfxA2WHelper et AfxW2AHelper dans le code source MFC dans \msdev\mfc\src et l'utilisation de OLE2T, T2OLE, OLE2CT et T2COLE dans le code source MFC dans \msdev\mfc\src. Ces fonctions permettent au code d'être compilée pour Unicode ou ANSI selon si la définition de préprocesseur _UNICODE a été effectuée. Par exemple, l'appel de CreateFileMoniker dans l'exemple ci-dessus peut être effectué comme suit avec les macros MFC :
USES_CONVERSION;
GetOpenFileName(&ofn);
CreateFileMoniker(T2OLE(ofn.lpstrFile), &pmk);
				
si _UNICODE est défini, T2OLE est définie comme suit :
inline LPOLESTR T2OLE(LPTSTR lp) { return lp; }
				
si _UNICODE n'est pas défini, T2OLE est définie comme suit :
#define T2OLE(lpa) A2W(lpa)
				
T dans T2OLE indique que le type à convertir en une chaîne OLE (chaîne Unicode) est une chaîne Unicode lorsque _UNICODE est défini et une chaîne ANSI Lorsque _UNICODE n'est pas défini. De même LPTSTR est défini comme un pointeur vers une chaîne Unicode lorsque _UNICODE est défini et comme un pointeur vers une chaîne ANSI Lorsque _UNICODE n'est pas défini. T2OLE ne fait pas de conversion Lorsque _UNICODE est défini (LPTSTR == LPOLESTR). Lors de l'Unicode n'est pas défini, A2W est appelée. A2W convertit une chaîne ANSI en Unicode comme suit :
#define A2W(lpa) (\ 
        ((LPCSTR)lpa == NULL) ? NULL : (\ 
            _convert = (strlen(lpa)+1),\ 
            AfxA2WHelper((LPWSTR) alloca(_convert*2), lpa, _convert)\ 
        )\ 

)
				
AfxA2WHelper utilise MultiByteToWideChar pour effectuer la conversion.

Les macros de conversion MFC utilisent _alloca pour allouer de l'espace à partir de la pile du programme pour la chaîne convertie. L'espace est automatiquement désalloué lorsque l'appel de procédure est terminée. OLE requiert l'allocateur OLE être utilisée pour toutes les chaînes (données) qui seront allouées par un composant et libérées par une autre. Cela signifie que les chaînes passées par l'intermédiaire de paramètres out et in-out-paramètres d'interfaces OLE doivent être alloués avec l'allocateur OLE. Dans paramètres ne doivent pas être alloués avec l'allocateur OLE car l'appelant est responsable de leur libération. La plupart des API et de liaison / l'incorporation OLE interfaces les chaînes de passer en tant que dans Paramètres. Par conséquent, les macros de conversion MFC peuvent être utilisés dans la plupart des cas. Les macros de conversion MFC ne peut pas être utilisés pour les paramètres in-out, ou pour retourner des valeurs via des paramètres out, car ils n'allouent pas d'espace à l'aide de l'allocateur OLE. AnsiToUnicode et Unicode peuvent être utilisé dans ces cas.

Encore un autre ensemble de routines de conversion Unicode/ANSI peut être trouvé dans la colonne de Don Box sur OLE dans Microsoft Systems Journal, août 1995, vol. 10 n° 8, page 86. Don Box définit une classe C++ avec un opérateur de cast qui retournera une chaîne Unicode/ANSI converti. L'espace alloué est automatiquement libérée lorsque l'objet passe hors de portée. Cette classe peut être modifiée pour allouer à l'aide de l'allocateur OLE et ne pas libérer l'espace alloué pour les chaînes qui sont transmis via in-out ou paramètres de sortie.

Une des classes, String16, à partir de la colonne de Don Box qui convertit une chaîne ANSI en Unicode, suit. Une autre classe, ANSI, qui est similaire à celui-ci est utilisée pour ANSI pour la conversion Unicode. L'appel de CreateFileMoniker à partir de l'exemple précédent peut être effectué comme suit avec cette classe :
GetOpenFileName(&ofn);
CreateFileMoniker(String16(ofn.lpstrFile), &pmk);
				
dans le code ci-dessus, une instance de String16 est créée. Le constructeur de la classe convertit la chaîne ANSI en Unicode. L'implémentation du langage appellera l'opérateur de cast, opérateur const wchar_t *, pour effectuer un cast de ce paramètre pour le type de premier paramètre du CreateFileMoniker. L'opérateur de cast renverra la chaîne Unicode qui est passée à CreateFileMoniker. L'objet va détruire en cas de passage hors de portée.
// String16 //////////////////////////////////////////////////////// 
// Shim class that converts both 8-bit (foreign) and
// 16-bit (native) strings to 16-bit wideness

class String16 {
public:

// native and foreign constructors
    String16(const char *p8);
    String16(const wchar_t *p16);

// non-virtual destructor (this class is concrete)

  ~String16(void);

// native conversion operator

  operator const wchar_t * (void) const;
private:

// native wideness string
    wchar_t *m_sz;
// is foreign??
    BOOL m_bIsForeign;

// protect against assignment!

  String16(const String16&);

    String16& operator=(const String16&);
};

// native constructor is a pass-through

inline String16::String16(const wchar_t *p16)
: m_sz((wchar_t *)p16), m_bIsForeign(FALSE)
{
}

// simply give out the native wideness string

inline String16::operator const wchar_t * (void) const
{
  return m_sz;
}

// foreign constructor requires allocation of a native
// string and conversion

inline String16::String16(const char *p8)
: m_bIsForeign(TRUE)
{

// calculate string length

  size_t len = strlen(p8);

// calculate required buffer size (some characters may
// already occupy 16-bits under DBCS)

  size_t size = mbstowcs(0, p8, len) + 1;

// alloc native string and convert

  if (m_sz = new wchar_t[size])

    mbstowcs(m_sz, p8, size);

}

// delete native string only if synthesized in foreign constructor

inline String16::~String16(void) {
  if (m_bIsForeign)

    delete[] m_sz;

}
				

Propriétés

Numéro d'article: 138813 - Dernière mise à jour: mercredi 16 mars 2005 - Version: 2.4
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft OLE 4.0 sur le système suivant
    • Microsoft Windows NT 3.51 Service Pack 5
    • Microsoft Windows NT 4.0
    • Microsoft Windows 95
Mots-clés : 
kbmt kbcode kbhowto kbprogramming KB138813 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 138813
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com