C++: Jak převést pomocí WinApi text z ANSI do TCHAR
June 10, 2008 Category: Programování, Zkušenosti No Comments »
Při psaní ročníkového projektu na mě vyskočil problém, jak převést text v ANSI, který přečtu z ini souboru do TCHAR se kterým pracují WinApi funkce. Děkuji matousecovi, který mě nasměroval na funkci MultiByteToWideChar, která má právě toto ve svém popisu práce
int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar );
Jako codepage se vyplatí dát ACP (active codepage), flags stačí nastavit na 0. Třetí parametr je ukazatel na převáděný řetězec, čtvrtý jeho délka, pátý ukazatel na cílový řetězec a šestý délka bufferu pro cílový řetězec.
Bohužel nic není tak jednoduché, jak by se mohlo zdát. Tato funkce převádí z ANSI do WCHAR, ne do TCHAR. TCHAR je hromada maker, která dle situace buď znamená char a neboo WCHAR. Druhá zákeřnost spočívá v tom, jak dlouhý buffer si naalokovat na výstup.
Pokud dáme čtvrtý parametr rovný -1, tak je očekáván vstup ukončený nulou a délku si to zjistí samo. Pokud navíc dáme poslední parametr rovný 0, tak funkce vrátí potřebnou délku bufferu, ale do samotného bufferu nepíše nic (ani ho nepotřebuje, stačí dát místo něj null).
Protože je práce se samotnými char* resp TCHAR* docela krkolomná, tak není od věci mít řetězce uložené v std::string. Není ani problém mít string na TCHARy, prostě si jako datový typ dáme std::basic_string<TCHAR>. A nyní i kousek kódu, který dělá co od něj očekáváme:
#include <windows.h>
#include <string>
typedef std::basic_string<TCHAR> tstring;
tstring ANSItoTSTRING(std::string to_convert)
{
tstring tstr;
#ifdef UNICODE
size_t size = MultiByteToWideChar(CP_ACP,0,to_convert.c_str(),-1,0,0);
WCHAR *converted = new WCHAR[size];
MultiByteToWideChar(CP_ACP,0,to_convert.c_str(),-1,converted,size);
tstr = converted;
delete[] converted;
#else
tstr = to_convert; // V ansi modu je std::string to same co tstring
#endif
return tstr;
}
Samotné pole TCHARů ukončené nulou pak získáte např voláním ANSItoTSTRING(“běžešelemovací řůčovičky”).c_str();
Name: Michal Tuláček