Unicode-преобразования
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Поделитесь опытом использования API-функции WideCharToMultiByte (у кого этот опыт имеется).
Задача такая - нужно получить вместо русской буквы "А" символы "0430" (или просто два соответствующих байта), вместо "Б" - "0431" и так далее. А также интересует обратное преобразование.
В принципе, можно самому прописать таблицу соответствий, но не хочется туда пихать весь русский алфавит, да еще в придачу остальные славянские символы.
Написал: Booroondook(77)
Задача такая - нужно получить вместо русской буквы "А" символы "0430" (или просто два соответствующих байта), вместо "Б" - "0431" и так далее. А также интересует обратное преобразование.
В принципе, можно самому прописать таблицу соответствий, но не хочется туда пихать весь русский алфавит, да еще в придачу остальные славянские символы.
Написал: Booroondook(77)
А в чём проблема?
Module('Windows API')
MultiByteToWideChar(UINT Codepage,DWORD dwFlags,ULong LpMultuByteStr, !
Long cbMultiByte, ULong LpWideCharStr,Long cchWideChar),RAW,DWord,PASCAL
WideCharToMultiByte(UINT Codepage,DWORD dwFlags,ULong LpWideCharStr,Long cchWideChar, !
ULong lpMultuByteStr, Long cbMultiByte, Ulong LpDefalutChar,LpBool lpUsedDefalutChar), !
Raw,DWord,Pascal
GETACP(),RAW,DWORD,PASCAL
End
If WideCharToMultiByte(GetACP(),0,Address(UnicodeText),BufSize,Address(Buffer),BufSize+1,0,0).
Buffer[BufSize+1]='<0>'
Cpage - кодовая страница (получается как Cpage=GetACP())
UnicodeText - адрес юникода (должен кончаться на <0,0>)
BufSize - размер выходного буфера ( половина от размера юникода)
Buffer - куда класть результат
If MultiByteToWideChar(GetACP(),0,Address(Buffer),BufSize,Address(UnicodeText),BufSize*2+2).
Buffer должен кончаться на '<0>'
А напоследок маленькая рутинка преобразования HTML-строки из Unicode в ASCII
Переменная S содержит содержимое некоторого HTML-файла в Юникоде АБ ... . После завершения она перекодирована в ASCII. Может быть, это и нужно?
--
C уважением
Yuri
Адрес:yufil@mail.ru
Написал: ClaList(2)
Module('Windows API')
MultiByteToWideChar(UINT Codepage,DWORD dwFlags,ULong LpMultuByteStr, !
Long cbMultiByte, ULong LpWideCharStr,Long cchWideChar),RAW,DWord,PASCAL
WideCharToMultiByte(UINT Codepage,DWORD dwFlags,ULong LpWideCharStr,Long cchWideChar, !
ULong lpMultuByteStr, Long cbMultiByte, Ulong LpDefalutChar,LpBool lpUsedDefalutChar), !
Raw,DWord,Pascal
GETACP(),RAW,DWORD,PASCAL
End
If WideCharToMultiByte(GetACP(),0,Address(UnicodeText),BufSize,Address(Buffer),BufSize+1,0,0).
Buffer[BufSize+1]='<0>'
Cpage - кодовая страница (получается как Cpage=GetACP())
UnicodeText - адрес юникода (должен кончаться на <0,0>)
BufSize - размер выходного буфера ( половина от размера юникода)
Buffer - куда класть результат
If MultiByteToWideChar(GetACP(),0,Address(Buffer),BufSize,Address(UnicodeText),BufSize*2+2).
Buffer должен кончаться на '<0>'
А напоследок маленькая рутинка преобразования HTML-строки из Unicode в ASCII
Переменная S содержит содержимое некоторого HTML-файла в Юникоде АБ ... . После завершения она перекодирована в ASCII. Может быть, это и нужно?
Код: Выделить всё
ReplaceHex Routine ! Замена Unicode
Data
Loc:InPos Long
Loc:OutPos Long
Loc:Len Long
Loc:S1 String(1)
Code
Loc:InPos=1
Loc:OutPos=1
Loc:Len=Len(S)
Loop
If Loc:InPos>Loc:Len Then Break.
Loc:S1=S[Loc:InPos]
Case Loc:S1
Of '<0>'
Break
Of '&'
Loc:S1=S[Loc:InPos+1]
If Loc:S1='#'
I#=S[Loc:Inpos+2 : Loc:InPos+5]
If Inrange(I#,1040,1103)
Loc:S1=Chr(Val('А')+(I#-1040))
Elsif I#=1025
Loc:S1='Ё'
Elsif I#=1105
Loc:S1='ё'
Else
Loc:S1=''
End
S[Loc:OutPos]=Loc:S1
Loc:InPos+=7
Loc:OutPos+=1
Else
S[Loc:OutPos]=S[Loc:InPos]
Loc:InPos+=1
Loc:OutPos+=1
End
Else
S[Loc:OutPos]=S[Loc:InPos]
Loc:InPos+=1
Loc:OutPos+=1
End
End
S=Sub(S,1,Loc:OutPos-1)
Exit
C уважением
Yuri
Адрес:yufil@mail.ru
Написал: ClaList(2)
-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Unicode-преобразования
Здравствуйте!
Посмотрите, пожалуйста, что я делаю не так и почему при вызове функции WideCharToMultiByte компилятор выдает сообщение об ошибке прототипирования.
В GMap:
WideCharToMultiByte(UINT Codepage,DWORD dwFlags,ULong LpWideCharStr,Long cchWideChar, ULong lpMultuByteStr, Long cbMultiByte, Ulong LpDefalutChar,LpBool lpUsedDefalutChar), Raw,DWord,Pascal
GETACP(),RAW,DWORD,PASCAL
В локальных переменных:
loc:Unicode CString(255)
loc:ASCII CString(255)
Codepage Unsigned
BufSize Long
Вызов функции:
!--- Преобразование Unicode в ASCII----------------------
loc:Unicode = SUB(Buffer,1,10) !Информация, полученная с сайта в UTF-кодировке
Codepage = GetACP()
BufSize = Size(loc:ASCII) + 1
!If WideCharToMultiByte(GetACP(),0,Address(loc:Unicode),BufSize,Address(loc:ASCII),BufSize+1,0,0).
If WideCharToMultiByte(Codepage,0,Address(loc:Unicode),BufSize,Address(loc:ASCII),Size(loc:ASCII),0,0).
loc:ASCII[BufSize+1]='<0>'
VKUQ:UserName = loc:ASCII
Выдаются следующие ошибки:
Label in prototype not defined: UINT
Label in prototype not defined: LPBOOL
No matching prototype available
Посмотрите, пожалуйста, что я делаю не так и почему при вызове функции WideCharToMultiByte компилятор выдает сообщение об ошибке прототипирования.
В GMap:
WideCharToMultiByte(UINT Codepage,DWORD dwFlags,ULong LpWideCharStr,Long cchWideChar, ULong lpMultuByteStr, Long cbMultiByte, Ulong LpDefalutChar,LpBool lpUsedDefalutChar), Raw,DWord,Pascal
GETACP(),RAW,DWORD,PASCAL
В локальных переменных:
loc:Unicode CString(255)
loc:ASCII CString(255)
Codepage Unsigned
BufSize Long
Вызов функции:
!--- Преобразование Unicode в ASCII----------------------
loc:Unicode = SUB(Buffer,1,10) !Информация, полученная с сайта в UTF-кодировке
Codepage = GetACP()
BufSize = Size(loc:ASCII) + 1
!If WideCharToMultiByte(GetACP(),0,Address(loc:Unicode),BufSize,Address(loc:ASCII),BufSize+1,0,0).
If WideCharToMultiByte(Codepage,0,Address(loc:Unicode),BufSize,Address(loc:ASCII),Size(loc:ASCII),0,0).
loc:ASCII[BufSize+1]='<0>'
VKUQ:UserName = loc:ASCII
Выдаются следующие ошибки:
Label in prototype not defined: UINT
Label in prototype not defined: LPBOOL
No matching prototype available
-
- ✯ Ветеран ✯
- Сообщения: 5190
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
Unicode-преобразования
Либо в "Global Embeds" в "After global Includes" написать типа:
Либо подключить в проект svapifnc.inc (там эти функции прописаны).
Либо в svapifnc.inc посмотреть их описание.
Можно ещё подождать одиннадцатой версии с полной поддержкой Unicode
.
Код: Выделить всё
UINT EQUATE(UNSIGNED)
Либо в svapifnc.inc посмотреть их описание.
Можно ещё подождать одиннадцатой версии с полной поддержкой Unicode

We are hard at work… for you. 

-
- Старожил
- Сообщения: 238
- Зарегистрирован: 10 Ноябрь 2005, 23:07
- Откуда: Краснодар
- Благодарил (а): 6 раз
Unicode-преобразования
Прописал в указанное место вместе с UINT'ом и LPBOOL и все заработало. Спасибо!
Но результат работы не тот, который ожидался. Программа получает с сайта данные в Buffer, распарсивает их и... До внедрения обсуждаемой функции было: После применения функции преобразования стало: Куда дальше смотреть?
Но результат работы не тот, который ожидался. Программа получает с сайта данные в Buffer, распарсивает их и... До внедрения обсуждаемой функции было: После применения функции преобразования стало: Куда дальше смотреть?
- Дед Пахом
- Старичок
- Сообщения: 3306
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 51 раз
- Контактная информация:
Unicode-преобразования
Честно говоря, не вдаваясь в детали, могу сказать, что написан полный и опасный бред. Во-первых, почему всё в CString-ах? Во-вторых, посмотрите сюда:
BufSize = Size(loc:ASCII) + 1
loc:ASCII[BufSize+1]='<0>'
вторая строка делает присвоение за границами loc:ASCII.
В-третьих, WideCharToMultiByte надо вызывать дважды, первый раз с нулём вместо Size(loc:ASCII), тогда она вернёт размер строки, второй раз с эти размером.
BufSize = Size(loc:ASCII) + 1
loc:ASCII[BufSize+1]='<0>'
вторая строка делает присвоение за границами loc:ASCII.
В-третьих, WideCharToMultiByte надо вызывать дважды, первый раз с нулём вместо Size(loc:ASCII), тогда она вернёт размер строки, второй раз с эти размером.
С уважением, ДП
-
- ✯ Ветеран ✯
- Сообщения: 5190
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 26 раз
Unicode-преобразования
NewUser, посмотри файл svcom.clw. Там есть использование этой функции. Вдруг поможет.
We are hard at work… for you. 

Unicode-преобразования
Речь не идёт о UTF-8? Много раз рассылал класс CSTR, в котором это с полпинка
https://mega.co.nz/#!RlAilJIT!2hvwWBkAn ... J3FmCLcmvw
Там эта операция примерно так звучит
U Cstr
....
U.Set(MyString)
U.toUTF8()
После чего U.S содержит строку MyString, перекодированную в UTF-8. Ну и всякий другой сахар для работы со строками неопределённой длины - конкатенация, загрузка файла, сохранение в файл, загрузка из Blob, сохранение в Blob.
https://mega.co.nz/#!RlAilJIT!2hvwWBkAn ... J3FmCLcmvw
Там эта операция примерно так звучит
U Cstr
....
U.Set(MyString)
U.toUTF8()
После чего U.S содержит строку MyString, перекодированную в UTF-8. Ну и всякий другой сахар для работы со строками неопределённой длины - конкатенация, загрузка файла, сохранение в файл, загрузка из Blob, сохранение в Blob.