Сейчас на форуме: tyns777, bezumchik (+5 невидимых)

 eXeL@B —› Вопросы новичков —› Ресурсы типа String.
Посл.ответ Сообщение

Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 07 ноября 2019 21:14
· Личное сообщение · #1

Ребята, никто не пробовал выводить строчки из ресурсов PE(RT_STRING - 6) в лист бокс.Почему WideCharToMultiByte корректно определяет только русские и английские строчки. Все остальные языки заменяет английскими буквами, а корейские - китайские, вообще не видит, выдает знаки вопросов?




Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 07 ноября 2019 21:32
· Личное сообщение · #2

Code:
  1. int WideCharToMultiByte(
  2.   UINT                               CodePage,
  3.   DWORD                              dwFlags,
  4.   _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr,
  5.   int                                cchWideChar,
  6.   LPSTR                              lpMultiByteStr,
  7.   int                                cbMultiByte,
  8.   LPCCH                              lpDefaultChar,
  9.   LPBOOL                             lpUsedDefaultChar
  10. );

Про параметр CodePage читай

-----
2 оттенка серого




Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 07 ноября 2019 21:58
· Личное сообщение · #3

f13ndЯ так понимаю если выставить параметр CP_ACP, то функция пытается подобрать аналог символа Юникода к текущей кодовой странице. Из ресурсов можно извлечь только LangID. Пробовал подставлять в ручную значения. Ничего не помогает.




Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 07 ноября 2019 22:08 · Поправил: f13nd
· Личное сообщение · #4

zombi-vadim пишет:
Я так понимаю если выставить параметр CP_ACP, то функция пытается подобрать аналог символа Юникода к текущей кодовой странице.

Для этого W-функции в винде и есть, чтобы не преобразовывать в ANSI, а выводить юникоде. Тебе нужен юникодовый листбокс и юникод ему передавать.

-----
2 оттенка серого




Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 07 ноября 2019 22:20
· Личное сообщение · #5

f13ndЯ как то не горел желанием преобразовывать проект к юникоду. f13nd пишет:
W-функции
То есть вообщем единственный вариант насколько я вас понял это работать напрямую с юникодом? WideCharToMultiByte тут не поможет?




Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 07 ноября 2019 22:24
· Личное сообщение · #6

zombi-vadim пишет:
WideCharToMultiByte тут не поможет?

Ну если найдешь способ другой чарсет установить окну, то может и поможет. Я такого способа не знаю. LVM_SETUNICODEFORMAT можешь посмотреть, чтоб не жестить сильно над программой.

-----
2 оттенка серого


| Сообщение посчитали полезным: zombi-vadim

Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 07 ноября 2019 22:25
· Личное сообщение · #7

f13ndСпасибо за обьяснения.



Ранг: 19.5 (новичок), 8thx
Активность: 0.050.08
Статус: Участник

Создано: 07 ноября 2019 23:46
· Личное сообщение · #8

zombi-vadim пишет:
Я как то не горел желанием преобразовывать проект к юникоду.

так и не нужно.
ничего не мешает использовать в проекте с много байтовой кодировкой юникодные W-функции.



Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 08 ноября 2019 19:09 · Поправил: zombi-vadim
· Личное сообщение · #9

dezmand07dezmand07 пишет:
ничего не мешает использовать в проекте с много байтовой кодировкой юникодные W-функции.

Да ничего не мешает. Но насколько я разобрался в ситуации, корень зла в том что все окна в многобайтовом проекте ожидают ANSI строки, и им плевать что получают они юникод строку.Один фиг она будет преобразована в ANSI и выведена на экран в виде крокозяблов. А вот обходной путь требует копания на форумах, как поставить юникод чарсет окну в ручную. У меня пока не получается.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 08 ноября 2019 19:39
· Личное сообщение · #10

Если проект на Visual Studio, то
1) В свойствах проекта поменять General -> Character Set: Use Unicode Character Set
2) В файлах проекта перед символами " и ' поставить символ L
3) Все типы char заменить на wchar_t

-----
IZ.RU




Ранг: 158.4 (ветеран), 123thx
Активность: 0.140.49
Статус: Участник

Создано: 08 ноября 2019 19:44
· Личное сообщение · #11

zombi-vadim
Винда понятия не имеет ни о каких ansi-проектах. Все стандартные контролы реализованы чисто юникодовыми, A-функции просто конвертируют переданную мультибайтную строку в юникод и вызывают парную W-функцию. Всякие CCM_SETUNICODEFORMAT нужны только тем контролам, у которых нет раздельных A- и W-сообщений, чтобы они понимали, указатель на что ты им передаешь.

Добавлено спустя 4 минуты
DenCoder пишет:
2) В файлах проекта перед символами " и ' поставить символ L

Лучше использовать макрос TEXT(). Это сконпелируется в строку, соответствующую выбранной кодировке.

DenCoder пишет:
3) Все типы char заменить на wchar_t

Лучше на TCHAR, по той же причине. И не забывать при том / sizeof(TCHAR), когда в компайлтайме длину буфера вычисляешь.



Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 08 ноября 2019 20:45 · Поправил: zombi-vadim
· Личное сообщение · #12

DenCoder пишет:
В свойствах проекта поменять General -> Character Set: Use Unicode Character Set

zombi-vadim пишет:
Я как то не горел желанием преобразовывать проект к юникоду

CString в юникодовом проекте выдает мне правильные символы в лист бокс, но в многобайтовом - ерунду.
У меня много самописных функций для поиска и форматирования строки, даже трудно себе представить сколько времени займет их модификация. И все ради вывода строчек из ресурса в юникоде.

Добавлено спустя 12 минут
Code:
  1.          CString strOutput;
  2.          LPCWSTR temp = (LPCWSTR)((DWORD)WinINIR + Offset);
  3.          for (int i = 0; i < 256; i++)
  4.          {
  5.                  if (temp[i] != 0x00 )
  6.                  {
  7.                         strOutput += temp[i];
  8.                  }
  9.          }
  10.          m_box.AddString(strOutput);

Вот простейший пример, что тут можно сделать.Контрол не хочет видеть юникод строку.Можно только преобразовать проект к юникоду. иначе мусор на экране.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 08 ноября 2019 22:14
· Личное сообщение · #13

Преобразуй!

-----
IZ.RU


| Сообщение посчитали полезным: zombi-vadim

Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 08 ноября 2019 22:36
· Личное сообщение · #14

DenCoderОк) Я уже понял. Либо так либо никак.




Ранг: 271.2 (наставник), 331thx
Активность: 0.321.49
Статус: Участник

Создано: 09 ноября 2019 06:00 · Поправил: f13nd
· Личное сообщение · #15

zombi-vadim пишет:
А вот обходной путь требует копания на форумах, как поставить юникод чарсет окну в ручную.

Цэшнику наверное все равно будет понятна идея:
Code:
  1. pushdatanp db 'SysListView32'\,0
  2.          mov eax,[binMainWindowRect.bottom]
  3.          sub eax,[binMainWindowRect.top]
  4.          mov ecx,[binMainWindowRect.right]
  5.          sub ecx,[binMainWindowRect.left]
  6.          invoke CreateWindowExA,0,addr esp + 10*4,0,WS_CHILD+WS_VISIBLE+WS_TABSTOP+WS_BORDER+LVS_AUTOARRANGE+LVS_TYPEMASK+LVS_LIST+LVS_SINGLESEL+LVS_SHOWSELALWAYS,[binMainWindowRect.left],[binMainWindowRect.top],ecx,eax,[hwnd],0,[.MainWindowInfo.hInstance],0
  7.          mov [.MainWindowInfo.hLvTest],eax
  8. popdata
  9. invoke SendMessageA,[.MainWindowInfo.hLvTest],LVM_SETCOLUMNWIDTH,0,200
  10. pushdata pszLvItemText1,db 'Произвольный текст 1'\,0
  11.          pushdatanp LVITEM LVIF_TEXT
  12.                  invoke SendMessageA,[.MainWindowInfo.hLvTest],LVM_GETITEMCOUNT,0,0
  13.                  mov [esp + LVITEM.iItem],eax
  14.                  mov ecx,[pszLvItemText1]
  15.                  mov [esp + LVITEM.pszText],ecx
  16.                  invoke SendMessageA,[.MainWindowInfo.hLvTest],LVM_INSERTITEMA,0,esp
  17.          popdata
  18. popdata
  19. pushdata pszLvItemText2,db 0x45\,0x00\,0x69\,0x00\,0x6E\,0x00\,0x6D\,0x00\,0x61\,0x00\,0x6C\,0x00\,0x20\,0x00\,0x4B\,0x00\,\
  20.                                           0xF6\,0x00\,0x6C\,0x00\,0x6E\,0x00\,0x20\,0x00\,0x62\,0x00\,0x69\,0x00\,0x74\,0x00\,0x74\,0x00\,\
  21.                                           0x65\,0x00\,0x00\,0x00
  22.          pushdatanp LVITEM LVIF_TEXT
  23.                  invoke SendMessageW,[.MainWindowInfo.hLvTest],LVM_GETITEMCOUNT,0,0
  24.                  mov [esp + LVITEM.iItem],eax
  25.                  mov ecx,[pszLvItemText2]
  26.                  mov [esp + LVITEM.pszText],ecx
  27.                  invoke SendMessageW,[.MainWindowInfo.hLvTest],LVM_INSERTITEMW,0,esp
  28.          popdata
  29. popdata


На всякий случай исходник --> Link <--

-----
2 оттенка серого




Ранг: 73.1 (постоянный), 130thx
Активность: 0.040.23
Статус: Участник

Создано: 09 ноября 2019 14:41 · Поправил: RamMerlabs
· Личное сообщение · #16

f13nd
[зануда-mode]
invoke SendMessageW,[.MainWindowInfo.hLvTest],LVM_GETITEMCOUNT,0,0
mov [esp + LVITEM.iItem],eax

LVM_GETITEMCOUNT здесь вобщем-то лишний, можно сэкономить на SendMessage, указав в LVITEM.iItem просто что-то вроде 07FFFFFFFh, Item будет добавлен в конец списка.
[/зануда-mode]



Ранг: 16.3 (новичок), 2thx
Активность: 0.150.22
Статус: Участник

Создано: 11 ноября 2019 21:15
· Личное сообщение · #17

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


 eXeL@B —› Вопросы новичков —› Ресурсы типа String.
Эта тема закрыта. Ответы больше не принимаются.
   Для печати Для печати