Проблемы с Unicode
Не могли бы вы мне помочь какой-нить ссылкой на то, как использовать Unicode и MSVCpp. Хотелось бы, увидеть освещенность таких вопросов как применение TChar, разница между Unicode и _Unicode, перекодировка char в Unicode.
И поясните вот этот код пожалуйста:
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, ch, l,reinterpret_cast<LPWSTR>(&str) , nLength);
В примерах и статьях, которые я нашел, просто был передан адрес переменной str( тип TChar), а у меня че-то не работает и ругается... В чем дело?
_http://alexsoft.home.nov.ru/download/prog/Richter__2004_06_03.rar
Там в главе 1, часть 2 все про Unicode написано
Может кто-нить пояснит кусочек приведенного кода?
Спасибо:) Одновременно удачный и неудачный ответ:) Удачный, потому что этот ресурс со мной в одной сети, к нему дешевый доступ:) А неудачный, потому что я уже прочитал дважды вторую главу и там есть ответы не на все мои вопросы:(
Может кто-нить пояснит кусочек приведенного кода?
Может скажешь, что надобно. И приведи описания используемых переменных, а то не понятно, что за str такая типа TCHAR
функция преобразует символ размером l(скорей всего там 1 было, а не l) байт в UNICODE строку(символ).Да, еще, перед ch должен стоять & (&ch). Насчет параметров:
1)CP_ACP - ANSI code page
2)MB_PRECOMPOSED - Always use precomposed characters—that is, characters in which a base character and a nonspacing character have a single character value. This is the default translation option.
3)4)
5)reinterpret_cast<LPWSTR>(&str) - не знаю зачем выделил. Но эт тоже самое, что и (LPWSTR)&str. Только C++ Specific...
6)макс размер под str
Вобчем - читай Рихтера и обзаводись MSDN'ом
Вот рабочий пример, но со строкой...
#define _UNICODE
#include "TChar.h"
#include "stdafx.h"
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
char t[]="Моя первая строка в UNICODE!!!!";
TCHAR str[100];
int th=MB_PRECOMPOSED;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, t, -1,reinterpret_cast<LPWSTR>(str), 200);
MessageBox(NULL,str,_TEXT("ANSI - дикий ацтой :)"),MB_OK);
return 0;
}
А ты быстро читаешь :). Но могем и обяснить, раз не понятно:
функция преобразует символ размером l(скорей всего там 1 было, а не l) байт в UNICODE строку(символ).Да, еще, перед ch должен стоять & (&ch). Насчет параметров:
1)CP_ACP - ANSI code page
2)MB_PRECOMPOSED - Always use precomposed characters—that is, characters in which a base character and a nonspacing character have a single character value. This is the default translation option.
3)4)
5)reinterpret_cast<LPWSTR>(&str) - не знаю зачем выделил. Но эт тоже самое, что и (LPWSTR)&str. Только C++ Specific...
6)макс размер под str
Вобчем - читай Рихтера и обзаводись MSDN'ом
Вот рабочий пример, но со строкой...
#define _UNICODE
#include "TChar.h"
#include "stdafx.h"
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
char t[]="Моя первая строка в UNICODE!!!!";
TCHAR str[100];
int th=MB_PRECOMPOSED;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, t, -1,reinterpret_cast<LPWSTR>(str), 200);
MessageBox(NULL,str,_TEXT("ANSI - дикий ацтой :)"),MB_OK);
return 0;
}
Если надо в Wide Char ну и ставь WCHAR
char ch = 'a'; // ANSI
WCHAR wch;
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, &ch, 1,&wch, 1);
Пробуй, расскажешь
Кстати не 200 а 100 - написано же в Wide Char длина и не в байтах - поосторожней а то переполнение и вся программа летит
TCHAR - это макрос, если _UNICODE определен он заменяется на wchar_t,а если нет - на char.
Так что легче потом прогу переносить с UNICODE на ANSI.
имхо TCHAR лучше пользоваться. Хотя, здесь, при явном преобразовании ANSI в UNICODE WCHAR целесообразней...
А 200 - отвольное число, что б точно влезло :), а не 100*2
A2W - CHAR -> WCHAR
W2A - WCHAR -> CHAR
W2T - WCHAR -> TCHAR
A2T - CHAR -> TCHAR
T2W - TCHAR -> WCHAR
T2A - TCHAR -> CHAR
И аналогичные A2CW, W2CA, W2CT, A2CT, T2CW, T2CA
для xCHAR -> const yCHAR.
Пример:
TCHAR szMsg[] = TEXT("Сообщение");
TCHAR szCaption[] = TEXT("Заголовок");
USES_CONVERSION;
::MessageBoxW(NULL, T2W(szMsg), T2W(szCaption), MB_OK);
::MessageBoxA(NULL, T2A(szMsg), T2A(szCaption), MB_OK);
}
Это будет успешно откомпилено как под UNICODE, так и без него.
И кода меньше, а значит и ошибок.
to pavor
TCHAR - это макрос, если _UNICODE определен он заменяется на wchar_t,а если нет - на char.
Так что легче потом прогу переносить с UNICODE на ANSI.
имхо TCHAR лучше пользоваться. Хотя, здесь, при явном преобразовании ANSI в UNICODE WCHAR целесообразней...
А 200 - отвольное число, что б точно влезло :), а не 100*2
Так нельзя делать. Кроме того бессмыслено конверитировать в строку типа char при этом кодируя UNICODE.
Еще. Предположим ты хочешь конвертировать в 100 символов Юникода. Ты пишешь TCHAR str[100] и компилируешь код под юникод - все работает отлично, если конечно длина строки указана 100.
А теперь компилируешь для MultiByte. Функция ожидает буфер размером 200 байт, а у тебя массив будет CHAR str[100] и если конвертированная строка будет больше 50 символов то опять каюк.
В общем советую разделить код для UNICODE/MULTIBYTE препроцессорными директивами и написать свои макросы. Так как если что-то возращается, значит что-то выделяется(память). И более производительнее будет конвертировать в переменную в стеке либо переменную которая существует дольше, чем вызов данной функции.
Но поясните кто-нить разницу между UNICODE и _UNICODE, TCHAR и _TCHAR?
Но он ничего не имеет общего с
#define UNICODE
#define _UNICODE
Здесь UNICODE, _UNICODE - константы препроцессора.
_UNICODE - используется для функций и макросов в TChar.h. Если она(константа) определена - вызываются Unicode-версии функций, если нет - ANSI. Выглядит это примерно так:
typedef TCHAR unsigned short;
#endif
#ifndef _UNICODE
typedef TCHAR char;
#endif
UNICODE - То ж самое, только для API-функций и типов.
Т.е. если б в моем примере не испльзовался
#define UNICODE
вызывалась бы ANSI версия функции MessageBox
А без
#define _UNICODE
TCHAR бы стала char, а не unsigned int
Насчет, TCHAR и _TCHAR - кажись нет никакой разницы...
Но я для себя решил использовать _TCHAR ввиду того, что в стандартном шаблоне консольного приложения используется именно он при передаче указателя на массив аргументов командной строки в функцию int _tmain(int argc, _TCHAR* argv[]):)