Проблема с преобразованием ...

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
Post Reply
Wintermute
Knows some wx things
Knows some wx things
Posts: 38
Joined: Tue May 26, 2009 8:39 am
Location: Moscow, Russia
Contact:

Проблема с преобразованием ...

Post by Wintermute »

Проблема с преобразованием регистра русских букв (Unicode)
Всем доброго времени суток!
Может, кто уже сталкивался...
Возникла проблема с преобразованием регистра русских букв в Unicode build'е. Они преобразуются в кракозябры.
Image
Пытался нагуглить, читать исходники, но нашёл только, что мой компилятор (указан ниже) поддерживает tchar (следовательно, wchar_t), а макро wxToupper (wxTolower) определено как _totupper (_totlower, соответственно). А что это такое, найти не удалось.
Подкиньте, плиз, какую-нибудь идейку — может, я просто туплю...

Заранее спасибо!

OS: Windows XP Professional SP2 (MUI language: English)
Borland C++ Builder 6
wxWidgets 2.8.8
FAQ
1. What the ... ?
2. Again what the ... ?
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

Дай кусок кода, который у тебя подобное выдает.
И это, Билдер - это самый худший выбор их того, что у тебя был. У него еще к тому же ограничение на размер бинарника и поэтому wx'овые проги могут валиться на ровном месте без видимых на то причин. Но ладно, код давай, будем смотреть.
Wintermute
Knows some wx things
Knows some wx things
Posts: 38
Joined: Tue May 26, 2009 8:39 am
Location: Moscow, Russia
Contact:

Post by Wintermute »

Билдер — единственное, что у меня было... =)
Вот, значит, кусок:

Code: Select all

bool Disambiguate(wxArrayString& files, wxArrayString& names, CorrM *corr, const wxString& ignore)
{
// ...
    wxArrayString a_files, a_names;
    wxFileName fname;
    wxString str;
    wtfArrayNames sfiles;
    size_t i, j, cnt, fcnt, ncnt;

#ifdef wtfUTIL_H_DEBUG
    wxLogMessage(wxT("Normalizing files list...\n"));
#endif
    cnt = files.GetCount();
    fcnt = 0;
    for (i = 0; i < cnt; i++)
    {
        j = 0;
        str = wxT("");
        while (j < files[i].Len())
        {
            if (ignore.Find(files[i][j]) == wxNOT_FOUND)
            {
                str += files[i][j];
            }
            j++;
        }
        if (str.Len() > 0)
        {
            fname.Assign(str);
            fname.Normalize(wxPATH_NORM_CASE | wxPATH_NORM_TILDE);
            str = fname.GetFullPath();
        }
        a_files.Add(str);
        if (str.Len() > 0)
        {
            if (sfiles.count(str))
            {
                return false;
            }
            sfiles[str] = i;
            fcnt++;
        }
#ifdef wtfUTIL_H_DEBUG
        wxLogMessage(wxT("  ") + files[i] + wxT(" => ") + str + wxT("\n"));
#endif
    }
// ...
}
Вот декларации типов:

Code: Select all

WX_DECLARE_STRING_HASH_MAP(size_t, wtfArrayNames);
WX_DECLARE_HASH_MAP(size_t, size_t, wxIntegerHash, wxIntegerEqual, CorrM );
Ну и wtfUTIL_H_DEBUG определён.

Кстати, проблема возникает и в таком коде (если в строке name есть русские буквы):

Code: Select all

wxMessageBox(name + wxT(" => ") + name.Upper(), wxT("Case conversion: to upper"), wxOK);
FAQ
1. What the ... ?
2. Again what the ... ?
borr_1
Super wx Problem Solver
Super wx Problem Solver
Posts: 362
Joined: Wed Mar 07, 2007 8:10 am
Location: Russia, Shakhty

Post by borr_1 »

Upper Lower это старая проблема смотри тут
http://forums.wxwidgets.org/viewtopic.php?t=21605

А вместо Buildera возми MinGW 3.4.5 (или 4.2.1 он стабильный) B CodeLite(тут CodeCompletion и она более удобная) + CodeBlock(тут неплохой генератор формочек) и глянь еще wxFormBuilder(это просто генератор форм) там качать всего метров 100, поверь не пожалеешь.
И вот функции взяты из FlameRobin

Code: Select all

//-----------------------------------------------------------------------------
//! converts wxString to std::string(Unicode->ANSI)
std::string MyDataGrid::wx2std(const wxString& input, wxMBConv* conv)
{
    if (input.empty())
        return "";
    if (!conv)
        conv = wxConvCurrent;
    return std::string(input.mb_str(*conv));
}
//-----------------------------------------------------------------------------
//! converts std:string to wxString(ANSI->UNICODE)
wxString MyDataGrid::std2wx(const std::string& input, wxMBConv* conv)
{
    if (input.empty())
        return wxEmptyString;
    if (!conv)
        conv = wxConvCurrent;
    return wxString(input.c_str(), *conv);
}
//-----------------------------------------------------------------------------

Wintermute
Knows some wx things
Knows some wx things
Posts: 38
Joined: Tue May 26, 2009 8:39 am
Location: Moscow, Russia
Contact:

Post by Wintermute »

Насколько я понимаю, в указаном топике у автора строка вообще не менялась. У меня же она меняется, но только русские буквы превращаются в кракозябры. (Хотя исходная строка нормальная.)
Один немец говорит, что у него русские буквы преобразуются нормально.
Сколько людей — столько мнений?! Image
Спасибо, конечно, за функции преобразования в/из std::string, но проблем с кодировкой у меня нет. Ну то есть все строки, которые я читаю из файлов преобразуются нормально (нужный конвертирующий экземпляр wxMBConv передаю в конструктор wxString), а вводимые через GUI — автоматически нормальные. (Проверял как выводом сообщением через, например, wxMessageBox, так и выводом в файл, с указанием ковертера wxCSConv(wxT("cp1251")).)

Спасибо за советы про компилятор и утилиты. Обязательно попробую.
(Проблем с траффиком у меня нет — анлим. Image )

Но всё же, возвращаясь к теме, как на самом деле обстоят дела с преобразованием регистра не латинских букв?
Хотелось бы иметь независимое от языка решение (раз уж используется Unicode).
Неужели это всё-таки глюк wxWidgets??? Или всё же компилятор в этом виноват?
FAQ
1. What the ... ?
2. Again what the ... ?
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

Code: Select all

wxLogMessage(wxT("  ") + files[i] + wxT(" => ") + str + wxT("\n")); 
wxString - не-POD тип. Я хз чо будет если ты ему скармливаешь прям строку.

чо происходит если скормить

Code: Select all

wxLogDebug(_("Йа Креведко"));
Т.е. просто чаровый массив с русским текстом?

Code: Select all

wxLogDebug(_("  %s => %s\r\n"), files[i].GetData(), str.GetData());
Чо будет если так сделать?
Wintermute
Knows some wx things
Knows some wx things
Posts: 38
Joined: Tue May 26, 2009 8:39 am
Location: Moscow, Russia
Contact:

Post by Wintermute »

Ну ведь files нормально отобразился. Проблема всё равно существует для Upper. Я выводил и сообщением wxMessageBox, и в файл с указанием конвертера wxCSConv(wxT("cp1251")).

Вот результат, предложенных команд:
Attachments
test1.png
test1.png (14.91 KiB) Viewed 3556 times
FAQ
1. What the ... ?
2. Again what the ... ?
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

Так... ладно. Вроде у Николая в блоге была корректная версия ТуАппер(). http://begemotov.net/wxwidgets - попробуй там поискать
Post Reply