Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.185.180] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Пишу сейчас мега-микропрогу: MkScreens
Народ заказал Ну - народ просит, значит сделаем. #define UNICODE, в нескольких десятках мест заменить CreateFile на CreateFileW, main на wmain, немного геморроя с переписыванием старенькой либы для разбора ключей командной строки и перевод эксцепшенов в используемой ДДЛи на Юникод... А вот теперь собственно к вопросам, от которых голова пухнет. Прога по задумке должна работать (и пока работает ) и в линейке НТ, и 9х. Спрашивается: как замутить такую ассоциацию на неё в реестре, чтобы гарантировано передавались имена файлов в Юникоде (даже если символы в их составе не входят в текущую раскладку ANSI)? Следующий вопрос. Хоть я и не добился от МСДН ответа, но мне кажется, что в функцию SetConsoleOutputCP под линейкой НТ можно передать как кодовую страницу Юникод. Я прав, или нет? Если я таки прав, то как заюзать в таком случае потоковые классы типа wcout под Win9x (пока вывод заточен на них, т.к. я замутил очень удобные ИМХО манипуляторы для изменения цвета текста в консоли - Что-то туплю по поводу ostream_withassign и консоли )? Если для 8-битной версии я могу с успехом использовать такой примитивнейший костыль: class OnTheFlyOEM { LPSTR lpszContainer; public: OnTheFlyOEM(LPCSTR lpszIn){ lpszContainer = strdup(lpszIn); CharToOem(lpszContainer, lpszContainer); } ~OnTheFlyOEM(){ if(lpszContainer) free(lpszContainer); } operator LPCSTR () const { return (LPCSTR)lpszContainer; } }; cout << OnTheFlyOEM(lpszFileName) << endl; То для Юникодного потока это, мягко говоря, не прокатит Делать две версии проги (через условную компиляцию), равно как и мутить варианты типа: if(bIsUnderNTAndUnicodeConsole) wcout << lpszFileName << endl; else cout << OnTheFlyOEM(lpszFileName) << endl; что-то не хочется Можно, конечно, написать свой класс для вывода на консоль, принимающий вывод как Юникодный, так и не Юникодный, и по ситуации делающий необходимые преобразования кодировок... Но неужели всё так запущено и ничего нельзя сделать попроще? |
Сообщ.
#2
,
|
|
|
Цитата barazuk @ Прога по задумке должна работать (и пока работает ) и в линейке НТ, и 9х. Даже я отказался от поддержки 9x... 8 лет прошло. Цитата barazuk @ в нескольких десятках мест заменить CreateFile на CreateFileW Зачем? Цитата barazuk @ Спрашивается: как замутить такую ассоциацию на неё в реестре, чтобы гарантировано передавались имена файлов в Юникоде (даже если символы в их составе не входят в текущую раскладку ANSI)? Эм. А разве ключи определяют набор символов? Цитата barazuk @ Хоть я и не добился от МСДН ответа, но мне кажется, что в функцию SetConsoleOutputCP под линейкой НТ можно передать как кодовую страницу Юникод. Я прав, или нет? Юникод -- не кодовая страница. Он в себе их содержит. |
Сообщ.
#3
,
|
|
|
Цитата B.V. @ Зачем? Потому что используются сторонние библиотеки, которые о Юникоде ни сном ни рылом. И мне гораздо проще использовать Юникод только там, где это реально нужно, чем обвязывать все вызовы конверсией и потом отлавливать баги из-за того, что где-нибудь передаётся имя файла, которое не может быть представлено в текущей кодировке ANSI. Цитата B.V. @ Даже я отказался от поддержки 9x... Поздравляю. А у меня дома стоит как основная система. И я счастлив Цитата B.V. @ Юникод -- не кодовая страница. Он в себе их содержит Не бредь. Хорошо, не кодовая страница, если тебе угодно (хотя устоявшихся русскоязычных терминов для подобных понятий всё равно не существует), а кодировка, если тебе от этого легче. Цитата B.V. @ Эм. А разве ключи определяют набор символов? А ты считаешь, что по двойному щелчку на файле, например, в Вин98 всегда по умолчанию Юникодное имя передаётся? Я например не уверен. Буду проверять. Вообщем, спасибо за развёрнутый ответ в стиле "оно тебе не надо" |
Сообщ.
#4
,
|
|
|
Цитата barazuk @ Не бредь. Хорошо, не кодовая страница, если тебе угодно (хотя устоявшихся русскоязычных терминов для подобных понятий всё равно не существует), а кодировка, если тебе от этого легче. Это не может быть ему угодно. Это действительно разные вещи. UNICODE (название говорит само за себя) содержит в себе уйму всяких таблиц символов. В то время как ANSI содержит в себе только одну - заданную локализацией системы. |
Сообщ.
#5
,
|
|
|
Хорошо, тогда UTF8 тоже не кодовая страница по-твоему?
|
Сообщ.
#6
,
|
|
|
Сообщ.
#7
,
|
|
|
Что касается вопроса. Может я тебя не правильно понял, заранее прощу прощения, но как насчет:
#ifdef UNICODE #define cout wcout #endif |
Сообщ.
#8
,
|
|
|
Я мож тоже не понял ну мож поможет
#ifdef _UNICODE int main() #endif int main() { //to do return 0; } Если не то то ПОРДОН!!! |
Сообщ.
#9
,
|
|
|
Цитата dedok[kelev(ruso)] @ Если не то то ПОРДОН!!! Определенно не то. И если будет объявлена _UNICODE, то компилятор расскажет о синтаксической ошибке. |
Сообщ.
#10
,
|
|
|
Цитата ALXR @ Определенно не то. И если будет объявлена _UNICODE, то компилятор расскажет о синтаксической ошибке. Компельни это в консоле Win32 , не какой ошибки ,мы в универи так делали для поддержание русского языка в консоле!!! |
Сообщ.
#11
,
|
|
|
Цитата B.V. @ Отсюда и до просветления. О, да! Цитата Использование различных кодовых страниц создаёт много неудобств как для пользователей, так и для программистов. При попытке прочесть текстовый файл при помощи кодовой страницы, несовместимой с той в которой он был создан, возникают крокозябры. В последние годы получил широкое распространение Unicode как альтернатива традиционным кодовым страницам Уровень изложения просто потрясает... Хорошо хоть внизу упомянули: Цитата Это незавершённая статья о компьютерном программном обеспечении. Вы можете помочь проекту, исправив и дополнив её. В чём тут просветление - большая загадка. А теперь обратимся к первоисточнику - МСДН: Цитата BOOL SetConsoleOutputCP( UINT wCodePageID // code page to set ); Parameters wCodePageID Specifies the identifier of the code page to set. The identifiers of the code pages available on the local computer are stored in the registry under the following key. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage Т.е. по версии мелкомягких (без лишних философствований), кодовая страница - это то, что перечислено в указанном ключе реестра ( ). Имеющий глаза, легко может увидеть там по ХРюнделем и UTF-7 (65000), и UTF-8 (65001). Более того, если написать такой мегакод: cout << GetConsoleOutputCP() << endl; SetConsoleOutputCP(65001); cout << GetConsoleOutputCP() << endl; То, как ни странно, на выходе получим: Цитата 866 65001 И на фоне восхищённых визгов об тотальной 32-битности и юникодности ХП можно было бы ожидать, что оно и работать будет - однако же нет, юникодные консольные функции являются полной профанацией - вместо того, чтобы реально использовать возможность вывода в консоль трутайпными юникодными шрифтами, добрые дядьки тупо делают преобразование Юникод -> OEM. Что весьма и весьма печально... Добавлено Хотя с другой стороны, один из вопросов снимается: как не пинай консоль, а вроке как ничего, окромя текущей ОЕМ-раксладки, в неё не выведешь. |
Сообщ.
#12
,
|
|
|
Хотел бы я посмотреть, как в текстовом режиме можно было бы расширить ASCII-таблицу до юникода. Шрифт еще на свой поменять можно...
Кстати, о UTF-7(8): Это и близко не юникод и не анси - это вообще, отдельная фигня. |
Сообщ.
#13
,
|
|
|
Цитата ALXR @ Хотел бы я посмотреть, как в текстовом режиме можно было бы расширить ASCII-таблицу до юникода. Шрифт еще на свой поменять можно... Мать... Опять путаем мягкое с тёплым. При чём тут текстовый режим к консоли? Или кто-то мне хочет сказать, что Вин32 консольное приложение прямо лезет к видеопамяти в текстовом режиме? Функции для вывода в консоль Юникодные (типа) - есть. Шрифты Юникодные - есть. Вопросы "совместимости" можно было бы и похерить - ведь, к примеру, размеры "консоли" вполне спокойно устанавливаются произвольным образом - никто ведь не делает трагедии из того, что при запуске ДОСовских прог (или просто при нажатии Alt+Enter) консоль какого-нибудь дикого размера типа 127 * 51 "прыгает" в поноэкранный режим и меняет размер на стандартный 80 * 25? Цитата ALXR @ Кстати, о UTF-7(8): Это и близко не юникод и не анси - это вообще, отдельная фигня. Это способ кодирования 16-битного Юникода в 8-битные последовательности. Короче: всё! Замяли вопрос! Независимо от того, как это называть, Юникода в консоли не прикрутили. Не захотели связываться. Точка. А имеющиеся Юникодные функции для вывода в консоль на самом деле тупые обёртки для 8-мибитных. И нафиг не нужны, по сути. Т.о. позвать CharToOem остаётся наиболее простым, переносимым и вменяемым способом вывода текста в консоль. |
Сообщ.
#14
,
|
|
|
Цитата barazuk @ Цитата ALXR @ Хотел бы я посмотреть, как в текстовом режиме можно было бы расширить ASCII-таблицу до юникода. Шрифт еще на свой поменять можно... Мать... Опять путаем мягкое с тёплым. При чём тут текстовый режим к консоли? Или кто-то мне хочет сказать, что Вин32 консольное приложение прямо лезет к видеопамяти в текстовом режиме? Функции для вывода в консоль Юникодные (типа) - есть. Шрифты Юникодные - есть. Вопросы "совместимости" можно было бы и похерить - ведь, к примеру, размеры "консоли" вполне спокойно устанавливаются произвольным образом - никто ведь не делает трагедии из того, что при запуске ДОСовских прог (или просто при нажатии Alt+Enter) консоль какого-нибудь дикого размера типа 127 * 51 "прыгает" в поноэкранный режим и меняет размер на стандартный 80 * 25? Цитата ALXR @ Кстати, о UTF-7(8): Это и близко не юникод и не анси - это вообще, отдельная фигня. Это способ кодирования 16-битного Юникода в 8-битные последовательности. Короче: всё! Замяли вопрос! Независимо от того, как это называть, Юникода в консоли не прикрутили. Не захотели связываться. Точка. А имеющиеся Юникодные функции для вывода в консоль на самом деле тупые обёртки для 8-мибитных. И нафиг не нужны, по сути. Т.о. позвать CharToOem остаётся наиболее простым, переносимым и вменяемым способом вывода текста в консоль. Кто тут путает теплое с мягким, так это Вы. Текстовый режим в консоли предстает Вашим очам при нажатии комбинации клавиш Ctrl+Enter. Черное окошко - по сути эмуляция этого текстового режима. Кстати видеопамять (да-да, та самая, что когда-то лежала по адресу 0xb8000) также имеет место быть. Записали строчечку в консоль, извольте видеть ее в имитации видеопамяти... да-да, по тому же самому адресу - 0xb8000. Функции юникодные преобразуют юникодную строку в ANSI-строку в соответствии с локализацией системы. Право неудобно было бы заниматься конвертацией юникод-строки в ANSI перед выводом ее в консоль каждый раз. Больше того(!) есть 2 типа ф-ций CharToOem() и OemToChar() - соответственно WIDE-char (CharToOemW() / OemToCharW()) и ANSI-char (CharToOemA() / OemToCharA()). У текстового режима разнообразие разрешений поскуднее, конечно, чем у графического, но тоже имеет место быть. Есть и 80х50 и еще больше. И каких там только еще нет. В целом вывод следующий: Будь ты хоть семи пядей во лбу, но из консоли графическую среду с поддержкой юникода и тру-тайп шрифтов не получить. Консоль - это консоль и ни граммом больше. Хочется отличиться и сделать красиво? Так вперед, сделайте свою имитацию консоли, задефайните ф-ции типа WriteConsole или перегрузите cout на вывод в свою "консоль" и будет и юникод и тру-тайп шрифты и можно даже будет цветочки в ней рисовать. И в целом не следует путать ф-ции типа Wide-char с юникод-шрифтами. |
Сообщ.
#15
,
|
|
|
Цитата ALXR @ И в целом не следует путать ф-ции типа Wide-char со юникод-шрифтами Угу. Угу. То есть Юникод как бы вроде и есть, только его нет. Что и требовалось доказать. Цитата ALXR @ Записали строчечку в консоль, извольте видеть ее в имитации видеопамяти... Вот именно. Можно было сделать Юникодную 16-тибитную консоль. В оконном режиме - отображать во всём великолепии. В полноэкранном - делать CharToOem и рисовать, что получится. Не вижу никаких принципиальных проблем. Более того, можно было просто создать отдельный подвид - "чисто Юникодная консоль" - которую не давать разворачивать в полноэкранку. Можно ещё кучу вариантов было бы придумать... Если бы было желание. Тем более, что в ХП "загрузка в режиме консоли" - всё равно производится в графическом режиме, а уже там в окошке запускаетсяопять-таки эмуляция Для меня просто странно при восторженных визгах о революционности, тотальноей 32-битности и юникодности без позорных пережитков прошлого, наблюдать такое убожество, когда можно было тучу более других вариантов устроить. |