Вопрос «ламерский», но всё же надеюсь, что модераторы меня не накажут, оштрафовав или отправив почитать MSDN.
(читал … да видно сильно я тупой :( ).
Вопрос, собственно, в том, что лучше использовать при программировании в среде VC++ 7.0 приложений, с точки зрения удобства разработки и гибкости в локализации? Из вашего опыта, а не по книжкам?
MS предлагает для этой цели использовать, как UNICODE, так и альтернативу – MBCS. Хотелось бы услышать ответы с акцентом для следующих случаев:
1) разрабатывается проект практически полностью в MFC, например, архитектуры CDoment/CView, или Dialog-based. Практически все строки в ресурсах.
2) Тоже, но кроме классов контролов MFC, достаточно часто используются не MFC обёртки контролов WinAPI. Строки могут быть как в ресурсах, так и константами непосредственно в коде.
3) Программирование без использования каркасных библиотек. Например, используем только WinAPI.
С MBCS вроде, как всё получается «автоматически», но всёж Майкрософт рекомендует переходить полностью на UNICODE. C UNICODE вроде всё универсально, работает железобетонно, да появляется дополнительная (может и не очень кстати малая) работа по конвертации строк, например, используемых строковых констант MBCS в UNICODE, по выделению достаточной памяти для хранения строк контролов и т.д.
ПС. Не откажите в том, чтоб сразу меня не послать на юникод;))))
Подскажите, пожалуйста.
В коде ниже UNICODE-проекта не делается преобразования строки при помощи MuliByteToWideChar. При копиляции в VC++ 7.0, при дефолтовых региональных настройках Russian XP (eng.) – имеем нормальные русские символы:
> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM > wParam, LPARAM lParam) > { > … > switch (message) { > case WM_PAINT: > hdc = BeginPaint(hWnd, &ps); > GetClientRect(hWnd,&Rect); > DrawText (hdc, _T("Привет") , -1, Я так понимаю вопросы здесь?
_T() это макрос из tchar.c, который в зависимости от наличия макроса _UNICODE (именно с подчеркиванием) делает или L"Привет" или просто "Привет".
> Вопросы: > Как такое возможно? Что?
> Кто выполняет эти преобразования? Компилятор. Стандарт языка C++ предусматривает два вида строковых литералов: "string" - обычная ASCII-строка и L"string" - Unicode-строка (аналогично 'c' и L'c')
> Что происходит с памятью, выделенной для строки? Ничего она просто попадает в data-секцию в готовом к употреблению виду.
> Спасибо. Если я неправильно понял суть вопроса - скажи
[C++] Уточняю - на сколько я протормозил ;)))26.04.04 22:04 Автор: void <Grebnev Valery> Статус: Elderman
> DrawText (hdc, _T("Привет") , -1, > Я так понимаю вопросы здесь? > _T() это макрос из tchar.c, который в зависимости от > наличия макроса _UNICODE (именно с подчеркиванием) делает > или L"Привет" или просто "Привет".
Это понятно. Было не понятно, как копилер в зависимости от региональных настроек ОС компилит строку? Что он при этом делает? Как определяет кодовую страничку для преобразования? См. ниже.
> > Кто выполняет эти преобразования? > Компилятор. Стандарт языка C++ предусматривает два вида > строковых литералов: "string" - обычная ASCII-строка и > L"string" - Unicode-строка (аналогично 'c' и L'c')
Как ты считаешь, что находится в строках с-кода (т.е. в тексте), когда мы редактируем файл в
IDE MS VS? Я просто не проверял.
А если я, к примеру, японец, и пишу японскую программу на японском компьютере (пользуясь IDE MS VS), где в тексте программы создаю японское привет _T(" здесь пишу иероглифами ")? Ты думаешь, что там будет строка с однобайтными символами?
> > Что происходит с памятью, выделенной для строки? > Ничего она просто попадает в data-секцию в готовом к > употреблению виду.
Я имел ввиду не то, где она будет расположена, а то, насколько корректно компиллер сможет определить требуемое число байт, если он корректно распознаёт символы UNICODE на стадии компиляции.
В частности, меня смутили заявления MS, что желательно строки в ресурсах делать длиннее требуемых на 30 % (наверное, заполнять пробелами ?). Я не понимаю, зачем это необходимо делать.
И надо ли на самом деле?
> Если я неправильно понял суть вопроса - скажи
Суть вопроса была в том, что я не понимал, откуда компилер берёт информацию для преобразования строки _T("Привет") в соответствии с русской кодировкой? При этом предполагалось, что мы не используем преобразование в явном виде при помощи MultiByteToWideChar, а компилер должен сам догадаться каким-то образом, что русские символы следует конверировать в русскую кодировку UNICODE.
По тому, что нормальность, или не нормальность перекодировки зависит от региональных настроек ОС - можно было догадаться, что если компилеру не указывать ничего о кодировке, то будет использованы установки по-умолчанию ОС. Меня смущала эта неопределённость, в некотором смысле.
Парни с одного из российских форумов только-только мне подсказали, мол для очистки совести попробуй
#pragma setlocale(.....) ;)))
Я попробовал и понял, какой я идиот. ;))) Нет, чтоб покопать самому в директивах компиллера ;))) Теперь мне стыдно ;)))
Это меня удовлетворило. Теперь понятно, что неопределённости нет. Либо компиллер будет использовать настройки ОС ( если ему ничего не подсказывать про кодировку, например, русскую ), либо можно явно указывать, что на стадии компиляции все строки должны быть преобразованы в UNICODE стоки с русскими символами, если мы используем #pragma setlocale(.....)
Теперь я рад, что хоть и в надуманном примере, но процесс управляемый ;))))
Теперь дополнительные вопросы:
1) Почему в stdafx.h проекта требуется одновременные декларации
#define UNICODE
#define _UNICODE
Только одного из символов недостаточно. Появляются ошибки компиллера. Проект - чисто winapi.
2) Почему #pragma setlocale ни как не отражается на строках в ресурсах. Там важно другое - в какой секции расположены строковые ресурсы или строки элементов управления.
так как у тебя #define _unicode, то _т("привет") уже unicode...27.04.04 00:00 Автор: + <Mikhail> Статус: Elderman
> > DrawText (hdc, _T("Привет") , -1, > > Я так понимаю вопросы здесь? > > _T() это макрос из tchar.c, который в зависимости от > > наличия макроса _UNICODE (именно с подчеркиванием) > делает > > или L"Привет" или просто "Привет". > > Это понятно. Было не понятно, как копилер в зависимости от > региональных настроек ОС компилит строку? Что он при этом > делает? Как определяет кодовую страничку для > преобразования? См. ниже. > > > > Кто выполняет эти преобразования? > > Компилятор. Стандарт языка C++ предусматривает два > вида > > строковых литералов: "string" - обычная ASCII-строка и > > L"string" - Unicode-строка (аналогично 'c' и L'c') > > Как ты считаешь, что находится в строках с-кода (т.е. в > тексте), когда мы редактируем файл в > IDE MS VS? Я просто не проверял. > А если я, к примеру, японец, и пишу японскую программу на > японском компьютере (пользуясь IDE MS VS), где в тексте > программы создаю японское привет _T(" здесь пишу > иероглифами ")? Ты думаешь, что там будет строка с > однобайтными символами? > > > > Что происходит с памятью, выделенной для строки? > > Ничего она просто попадает в data-секцию в готовом к > > употреблению виду. > > Я имел ввиду не то, где она будет расположена, а то, > насколько корректно компиллер сможет определить требуемое > число байт, если он корректно распознаёт символы UNICODE на > стадии компиляции. > В частности, меня смутили заявления MS, что желательно > строки в ресурсах делать длиннее требуемых на 30 % > (наверное, заполнять пробелами ?). Я не понимаю, зачем это > необходимо делать. > И надо ли на самом деле? > > > Если я неправильно понял суть вопроса - скажи > > Суть вопроса была в том, что я не понимал, откуда компилер > берёт информацию для преобразования строки _T("Привет") в > соответствии с русской кодировкой? При этом предполагалось, > что мы не используем преобразование в явном виде при помощи > MultiByteToWideChar, а компилер должен сам догадаться > каким-то образом, что русские символы следует конверировать > в русскую кодировку UNICODE. > По тому, что нормальность, или не нормальность > перекодировки зависит от региональных настроек ОС - можно > было догадаться, что если компилеру не указывать ничего о > кодировке, то будет использованы установки по-умолчанию ОС. > Меня смущала эта неопределённость, в некотором смысле. > > Парни с одного из российских форумов только-только мне > подсказали, мол для очистки совести попробуй > #pragma setlocale(.....) ;))) > > Я попробовал и понял, какой я идиот. ;))) Нет, чтоб > покопать самому в директивах компиллера ;))) Теперь мне > стыдно ;))) > Это меня удовлетворило. Теперь понятно, что > неопределённости нет. Либо компиллер будет использовать > настройки ОС ( если ему ничего не подсказывать про > кодировку, например, русскую ), либо можно явно указывать, > что на стадии компиляции все строки должны быть > преобразованы в UNICODE стоки с русскими символами, если мы > используем #pragma setlocale(.....) > Теперь я рад, что хоть и в надуманном примере, но процесс > управляемый ;))))
так как у тебя #define _UNICODE, то _Т("Привет") уже UNICODE и ни о каких преобразованиях и речи быть не должно.
другое дело если у тебя _MBCS или SBCS
> > Теперь дополнительные вопросы: > > 1) Почему в stdafx.h проекта требуется одновременные > декларации > #define UNICODE > #define _UNICODE
UNICODE - используются в "windows headers"
_UNICODE - используются в "C-runtime/MFC headers"
> > Только одного из символов недостаточно. Появляются ошибки должно быть достаточно одного какого-либо define, другой define автоматически
> компиллера. Проект - чисто winapi. > > 2) Почему #pragma setlocale ни как не отражается на строках > в ресурсах. Там важно другое - в какой секции расположены
наверно надо #pragma setlocale в ресурсе тоже(это для _MBCS или SBCS?). вообще ни когда не имел проблем если исползовать UNICODE, windows то UNICODE-ная.
> строковые ресурсы или строки элементов управления.
Верно, что если установлено #define _unicode, то...27.04.04 06:05 Автор: void <Grebnev Valery> Статус: Elderman
> так как у тебя и ни о каких преобразованиях и речи быть не должно. > другое дело если у тебя _MBCS или SBCS
Верно, что если установлено #define _UNICODE, то _Т("Привет") уже UNICODE.
Но если не использовать #pragma setlocale("rus"), и при этом региональная настройка ОС - English,
то вместо русских символов в окне "печатаются" закорючки.
Русские символы получаются, если имеется хотя быодноиз трёх:
1) региональные настройки - Russian
2) #pragma setlocale("rus")
3) Явно используем MultiByteToWideChar и в функцию рисования передаём буфер, а не константу.
Так работает ;))) Я ж не виноват, что M$ так замутил ;)))
> UNICODE - используются в "windows headers" > _UNICODE - используются в "C-runtime/MFC headers"
Таким образом, правильно ли будет сказать, что в проекте winapi, как правило, следует использовать и то, и другое (одновременно оба define) ?
> наверно надо #pragma setlocale в ресурсе тоже(это для _MBCS > или SBCS?). вообще ни когда не имел проблем если > исползовать UNICODE, windows то UNICODE-ная.
1) расположение #pragma setlocale в ресурсе никак не сказывается на результатах компиляции.
2) дык проблем особых нет. Всё компилируется. Ни так, дык иначе. Та неопределённость, которая была, вроде как пока снята.
ПС. Спасибо за Вашу реакцию на мои, возможно, дурацкие вопросы.
Верно. Кстати, все юникодные проекты, которые я видел,...27.04.04 10:38 Автор: amirul <Serge> Статус: The Elderman
> > UNICODE - используются в "windows headers" > > _UNICODE - используются в "C-runtime/MFC headers" > > Таким образом, правильно ли будет сказать, что в проекте > winapi, как правило, следует использовать и то, и другое > (одновременно оба define) ? Верно. Кстати, все юникодные проекты, которые я видел, определяли обе константы.
ЗЫ: Кстати, VS поддерживает файлы прямо в Unicode. Так что вместо включения #pragma (а для ресурсного файла вообще без альтернативы) можно хранить файл прямо в Unicode. Как создать из VS IDE я так и не нашел (хотя не сильно активно искал), но можно перекодировать уже готовые файлы тем же Notepad-ом и все будет работать.
Причем можно использовать любые схемы трансляции юникода (в том числе и UTF-8 если русского текста не очень много, а места жалко).
Спасибо за мнение, amirul!27.04.04 23:30 Автор: void <Grebnev Valery> Статус: Elderman
> ЗЫ: Кстати, VS поддерживает файлы прямо в Unicode. Так что > вместо включения #pragma (а для ресурсного файла вообще без > альтернативы) можно хранить файл прямо в Unicode. Как > создать из VS IDE я так и не нашел (хотя не сильно активно > искал), но можно перекодировать уже готовые файлы тем же > Notepad-ом и все будет работать. > Причем можно использовать любые схемы трансляции юникода (в > том числе и UTF-8 если русского текста не очень много, а > места жалко).