FreeBasic
Главная
Вход
Регистрация
Пятница, 29.03.2024, 03:58Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Freebasic » Вопросы по языку FreeBasic » Перекодировка текста (с веб-страницы)
Перекодировка текста
WQДата: Воскресенье, 15.06.2014, 23:05 | Сообщение # 1
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Вот такой код:
Код
#Include "window9.bi"
Dim As Integer event
Dim As HWND hwnd
Dim As String*1024 sData
Dim As String sRet
Dim As Integer iBytes

hwnd=OpenWindow("",10,10,640,660) : CenterWindow(hwnd)

Dim As HINTERNET hOpen,hUrl

hOpen = InetOpen

hUrl = OpenUrl(hOpen,"http://news.yandex.ru/index.rss")

Do
  sRet &= Left(sData , iBytes)
  iBytes = InetReadFile(hUrl,Cast(String Ptr,@sData),1024)
Loop Until iBytes = 0

EditorGadget(1,10,10,600,600, sRet)

Do
  event=WaitEvent()
  If Event=EventClose Then End
Loop


Нужно перекодировать, чтобы читался текст на русском. Возможно ли это?
 
haavДата: Понедельник, 16.06.2014, 18:22 | Сообщение # 2
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Код
#Include "window9.bi"
Dim As Integer event
Dim As HWND hwnd
Dim As String*1024 sData
Dim As String sRet
Dim As Integer iBytes  

Function unicodeTO (ProcStr AS ZString Ptr) AS String
   Var OutLen = MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, 0, 0)
   Dim AS WString Ptr WStrTemp = CAllocate(OutLen*2+2)
   MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, WStrTemp, OutLen)
   OutLen = WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, 0, 0, 0, 0)
   Dim As ZString ptr szbuf
   Dim As String sRet
   szbuf = Callocate(OutLen)
   WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, CPtr(LPSTR, szbuf), OutLen, 0, 0)
   sRet = *szbuf
   Deallocate(szbuf)
   Deallocate(WStrTemp)
   Return sRet
End Function

hwnd=OpenWindow("",10,10,640,660) : CenterWindow(hwnd)

Dim As HINTERNET hOpen,hUrl

hOpen = InetOpen

hUrl = OpenUrl(hOpen,"http://news.yandex.ru/index.rss")

Do
   sRet &= Left(sData , iBytes)
   iBytes = InetReadFile(hUrl,Cast(String Ptr,@sData),1024)
Loop Until iBytes = 0  

EditorGadget(1,10,10,600,600, unicodeTO(StrPtr(sRet)))

Do
   event=WaitEvent()
   If Event=EventClose Then End
Loop


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
WQДата: Вторник, 28.10.2014, 14:21 | Сообщение # 3
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Спасибо!

Добавлено (28.10.2014, 14:21)
---------------------------------------------
Задача усложнилась - теперь нужно получить не обычную кирилицу, а расширенную, чтобы читался текст на казахском языке, сейчас эти символы заменяются вопросиками. А, вообще, возможно, и до иероглифов дойдет) Включил юникод, и теперь сообщение в конце кода может отображать такие символы, так что можно проверить.
Я так понимаю, функции не могут возвращать результат типа Wstring?

Код
#define UNICODE
#Include "window9.bi"
Dim As String*1024 sData
Dim As String sRet
Dim As Integer iBytes

Function unicodeTO (ProcStr As ZString Ptr) As String
   Var OutLen = MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, 0, 0)
   Dim As WString Ptr WStrTemp = Callocate(OutLen*2+2)
   MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, WStrTemp, OutLen)
   OutLen = WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, 0, 0, 0, 0)
   Dim As ZString Ptr szbuf
   Dim As String sRet
   szbuf = Callocate(OutLen)
   WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, CPtr(LPSTR, szbuf), OutLen, 0, 0)
   sRet = *szbuf
   DeAllocate(szbuf)
   DeAllocate(WStrTemp)
   Return sRet
End Function

Dim As HINTERNET hOpen,hUrl

hOpen = InetOpen

hUrl = OpenUrl(hOpen,"http://bilimsite.kz/rss.xml")

Do
   sRet &= Left(sData , iBytes)
   iBytes = InetReadFile(hUrl,Cast(String Ptr,@sData),1024)
Loop Until iBytes = 0

MessageBox(null, unicodeTO(StrPtr(sRet)), "Text", 0)


Сообщение отредактировал WQ - Вторник, 28.10.2014, 14:24
 
haavДата: Среда, 29.10.2014, 07:53 | Сообщение # 4
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата WQ ()
Я так понимаю, функции не могут возвращать результат типа Wstring?


Какие функции? Если из библиотеки window9 , то да все библиотека заточена под ASCII.


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
WQДата: Среда, 29.10.2014, 11:40 | Сообщение # 5
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Цитата haav ()
Какие функции? Если из библиотеки window9 , то да все библиотека заточена под ASCII.

Любые функции - если пишу возвращать результат типа Wstring, компилятор ругается.

А так еще два вопроса:
1) InetReadFile в принципе позволяет получить из сети всякие иероглифы и т.д.?
2) Если да, то как переделать unicodeTO из кода выше, чтобы добраться до этих символов?

Я разобрался с отображением unicod-символов средствами winapi, а теперь проблема в получении их с интернет-страниц.
 
haavДата: Среда, 29.10.2014, 13:32 | Сообщение # 6
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Цитата WQ ()
Любые функции - если пишу возвращать результат типа Wstring, компилятор ругается.


Ну как любые? Берем API функцию GetWindowText

Для исходника ASCII компилятор будет использовать эту декларацию:

Код
declare function GetWindowText alias "GetWindowTextA" (byval as HWND, byval as LPSTR, byval as integer) as integer


Для исходника Unicode эту:

Код
declare function GetWindowText alias "GetWindowTextW" (byval as HWND, byval as LPWSTR, byval as integer) as integer


Как видишь, в первом случае второй параметр принимает LPSTR или zstring ptr . Во втором случае LPWSTR или Wstring ptr.

Цитата WQ ()
InetReadFile в принципе позволяет получить из сети всякие иероглифы и т.д.?


Данная функция попросту заполняет данными переданный ей буфер. Что это будет за буфер, зависит от программиста. Функции глубоко наплевать на то: будет это Byte ptr или zstring ptr или integer ptr. Она возьмет указатель на буфер (то есть адрес начала буфера) , посмотрит на 3 параметр (сколько байт нужно считать) и считает столько , сколько получится за раз , совсем необязательно столько сколько указано в 3 параметре. То есть она как бы копирует данные с сетевого источника в твой буфер. А уж что ты дальше будешь делать со своим буфером, в какой будешь формат (текстовый или не текстовый) перегонять , это твое дело. К примеру ты передал буфер и после вызова функции в твоем буфере появились следующие байты:

CC E8 F0

Что это за байты??? Если ты хочешь видеть их в OEM формате, то получится что-то вроде этого:

Цитата
╠шЁ


А если в ASCII, то:

Цитата
Мир


В UTF-8 тоже что-то получится, но вряд ли я смогу сюда записать этот символ. Понимаешь, буфер один и тот же, а как ты представишь в текстовую информацию данный буфер, зависит от тебя.

Цитата
Если да, то как переделать unicodeTO из кода выше, чтобы добраться до этих символов?


WQ! Ты бы хоть немного почитал про функции MultiByteToWideChar, WideCharToMultiByte. Вся информация по ним есть на сайте мелкософта, а может даже есть где и русская инфа. А так и будешь постоянно только подставлять готовое, не понимая как это работает. Ладно , вот рабочий код для этого RSS:

Код
#define UNICODE
#Include "window9.bi"
Dim Shared As Byte bData(10000000)
Dim As Integer iBytes,iAllBytes
Dim shared As WString Ptr WStrTemp

Function unicodeTO (ProcStr As Byte Ptr) As WString Ptr
    Var OutLen = MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, 0, 0)
    WStrTemp = Callocate(OutLen*2+2)
    MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, WStrTemp, OutLen)
    OutLen = WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, 0, 0, 0, 0)
    Return WStrTemp
End Function

Dim As HINTERNET hOpen,hUrl

hOpen = InetOpen

hUrl = OpenUrl(hOpen,"http://bilimsite.kz/rss.xml")

Do
    iBytes = InetReadFile(hUrl,@bData(iAllBytes),1024)
    iAllBytes+=iBytes
    DeAllocate(WStrTemp)
Loop Until iBytes = 0

Dim msg As MSG

Dim As hwnd hwnd = CreateWindowEx(0,"#32770","RSS",WS_VISIBLE Or WS_OVERLAPPEDWINDOW,100,100,800,600,0,0,0,0)

setwindowtext(CreateWindowEx(0,"EDIT","",WS_VISIBLE Or WS_CHILD Or ES_MULTILINE Or ES_AUTOVSCROLL _
  Or ES_AUTOHSCROLL Or WS_HSCROLL Or WS_VSCROLL,0,0,750,550,hwnd, 0,0,0),unicodeTO(@bData(0)))
   
While GetMessage(@msg,0,0,0)
     DispatchMessage(@msg)
     If msg.message=WM_COMMAND Then Exit While
Wend


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
WQДата: Среда, 08.07.2015, 23:02 | Сообщение # 7
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Цитата haav ()
WQ! Ты бы хоть немного почитал про функции MultiByteToWideChar, WideCharToMultiByte. Вся информация по ним есть на сайте мелкософта, а может даже есть где и русская инфа. А так и будешь постоянно только подставлять готовое, не понимая как это работает

Ну, конечно, я читал про эти функции) Просто я перехожу на Freebasic с Autoit, где поддержка юникода и некоторые другие вещи реализованы лучше, и, например, получение данных с такой интернет-страницы будет занимать одну строку кода.

Вот, кстати, что я написал сам, еще до того, как увидел ответ здесь:
Код
#define UNICODE
#Include "window9.bi"
Dim As String*1024 sData
Dim As String sRet
Dim As Integer iBytes

Function unicodeToW (ProcStr As WString Ptr) As WString Ptr
   Var OutLen = MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, 0, 0)
   Dim As WString Ptr WStrTemp = Callocate(OutLen*2+2)
   MultiByteToWideChar(CP_UTF8, 0, ProcStr, -1, WStrTemp, OutLen)
   'OutLen = WideCharToMultiByte(CP_ACP, 0, WStrTemp, -1, 0, 0, 0, 0)
   'DeAllocate(WStrTemp)
   Return WStrTemp
End Function

Dim As HINTERNET hOpen,hUrl

hOpen = InetOpen
hUrl = OpenUrl(hOpen,"http://bilimsite.kz/rss.xml")

Do
   sRet &= Left(sData , iBytes)
   iBytes = InetReadFile(hUrl,Cast(WString Ptr, @sData), 1024)
Loop Until iBytes = 0

Dim As WString*200000 sRetW
sRetW=*(unicodeToW(StrPtr(sRet)))

MessageBox(null, sRetW, "Text", 0)

Так что, думаю, я не безнадежен)

Обычно, прежде чем задавать вопрос на этом форуме, я стараюсь изучить всю возможную информацию по этому направлению, и решить проблему самостоятельно.
В данном конкретном случае, возможно, я поторопился, решение было ближе, чем я думал.

Код программы, которую я пишу, сейчас уже около 12000 строк, и это только половина. Если бы я каждый раз задавал вопросы, когда испытывал затруднения, то размер форума вырос бы в несколько раз)

Добавлено (08.07.2015, 23:02)
---------------------------------------------
К сожалению, опять проблема с кодировками
Работаю с IUP. Там для отображения юникода используется кодировка UTF8 (с версии 3.9), т.е., весь текст вводимый и выводимый любыми способами, будет в UTF8, в данном случае, в виде Zstring - крякозяблов. вообще это довольно удобно, т.к. эти zstring-строки можно обрабатывать обычными текстовыми функциями, а с wstring куча проблем
Как переводить из UTF8 в Wstring, я разобрался, например, бросаешь на форму файл с названием из иероглифов - отображается название файла и он открывается средствами WinApi (встроенные средства Freebasic не поддерживают юникод, по крайней мере, в версии 1.00)

А вот как перевестиWstring в UTF8 так, чтобы IUP могла показать их, разобраться не могу

Код:
Цитата
#include "inc/iup.bi"

#Define unicode
#include "windows.bi"
#include "crt.bi"

IupOpen(0,0)
?*IupVersion() ' > 3.9
IupSetGlobal("UTF8MODE","YES")
Dim Shared AS ZString Ptr WStrResult

Function unicode1(ProcStr As WString Ptr) As ZString Ptr
Var OutLen = MultiByteToWideChar(CP_ACP, 0, ProcStr, -1, 0, 0)
Dim AS WString Ptr WStrTemp = CAllocate(OutLen*2+2)
MultiByteToWideChar(CP_ACP, 0, ProcStr, -1, WStrTemp, OutLen)
OutLen = WideCharToMultiByte(CP_UTF8, 0, WStrTemp, -1, 0, 0, 0, 0)
WStrResult = Reallocate(WStrResult, OutLen)
WideCharToMultiByte(CP_UTF8, 0, WStrTemp, -1, CPtr(LPSTR, WStrResult), OutLen, 0, 0)
Deallocate(WStrTemp)
Return WStrResult
End Function

Dim As WString Ptr s

s=VarPtr(WChr(1199))

Dim As Ihandle Ptr ml
ml = IupMessageDlg()
IupSetAttribute(ml, "DIALOGTYPE", "WARNING")
IupSetAttribute(ml, "TITLE", "IupMessageDlg Test")
IupSetAttribute(ml, "VALUE", *unicode1(s))  ' "Т±")

IupPopup(ml, IUP_CURRENT, IUP_CURRENT)

IupMainLoop ()


WChr(1199) - ұ - буква казахского алфавита - взята для примера, а так нужно преобразовывать довольно большие тексты. В UTF8 эта буква выглядит как Т±
Функция unicode1 вроде бы должна переводить в  Zstring, но в итоге что-то не то.

Надо бы здесь на форуме выложить сборку IUP 3.15


Сообщение отредактировал WQ - Среда, 08.07.2015, 23:04
 
haavДата: Пятница, 10.07.2015, 11:17 | Сообщение # 8
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Для винды можно использовать функции MultiByteToWideChar и WideCharToMultiByte. Не знаю правда как с казахским...
Для Linux iconv

Вот пример перевода в UTF8 и обратно:

Код
#Include "windows.bi"

Dim As DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, "Здравствуй мир!", -1, NULL, 0)
Dim As WString Ptr wstr_ = Allocate(dwNum*2+2)
MultiByteToWideChar(CP_ACP, 0,"Здравствуй мир!" , -1, wstr_, dwNum)
dwNum = WideCharToMultiByte(CP_UTF8, 0, wstr_, -1, NULL, 0, NULL, NULL)
Dim As String utf8 = Space(dwNum)
WideCharToMultiByte(CP_UTF8, 0, wstr_, -1, utf8,dwNum , NULL, NULL)
DeAllocate(wstr_)
? RTrim(utf8)

dwNum = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0)
wstr_ = Allocate(dwNum*2+2)
MultiByteToWideChar(CP_UTF8, 0,utf8 , -1, wstr_, dwNum)
dwNum = WideCharToMultiByte(CP_ACP, 0, wstr_, -1, NULL, 0, NULL, NULL)
Dim As String ANSI = Space(dwNum)
WideCharToMultiByte(CP_ACP, 0, wstr_, -1, ANSI,dwNum , NULL, NULL)
DeAllocate(wstr_)
? RTrim(ANSI)
Sleep


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
WQДата: Пятница, 10.07.2015, 22:20 | Сообщение # 9
Полковник
Группа: Проверенные
Сообщений: 215
Репутация: 7
Статус: Offline
Спасибо!
Я еще обнаружил функции для работы с UTF в FLTK, вроде они кроссплатформенные.
А так в Ubuntu вроде все в UTF, например, если в названиях файлов есть иероглифы, Freebasic нормально с ними работает, в отличие от Win
 
Форум » Freebasic » Вопросы по языку FreeBasic » Перекодировка текста (с веб-страницы)
  • Страница 1 из 1
  • 1
Поиск: