Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Delphi |
![]() ![]() |
Топик располагается на нескольких страницах: 1 2 3 4 5 6 7 [все] |
Анна Петровна Member Откуда: Сообщений: 68 |
Крякозябры вместо русских символов на Windows 10 - при включенной опции Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире Есть программный код на Delphi 7, нормально работает под Windows XP/Vista/7/8/8.1 и до определенных пор на Windows 10. Работает практически при любых языковых настройках - т. к. для борьбы с крякозябрами на англоязычных XP/7 использовала SetThreadLocale(1049) RUSSIAN_CHARSET - в кодировке компонентов, шрифт Arial вместо стандартного MS Sans Serif и прочие ухищрения, что нашла в Сети - таким образом, добилась того, что всё нормально работает практически под любой Windows - при любых языковых настройках (даже если англоязычная Windows и основной язык - французский) Однако, в последних версиях Windows 10 в языковых настройках появилась опция "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире"/"Use Unicode UTF-8 for worldwide language support" - которая в некоторых случаях включена по умолчанию (кроме того, после её отключения - чтобы изменения вступили в силу - компьютер нужно перезагружать). Если эта опция включена - в программе вместо русских букв отображаются крякозябры и никакие ухищрения не помогают это исправить - кроме отключения данной галочки. Мне нужно - чтобы программа нормально отображала русские буквы - независимо от состояния данной галочки. Как я понимаю (возможно, ошибаюсь) - нужно как-то перехватывать WinAPI-метод из Kernel32.dll GetACP. В нормальном состоянии эта функция должна возвращать 1251. Она и возвращает 1251 в том числе на Windows 10 - при отключении этой галочки. При включении галочки данная функция возвращает 65001 и программа отображается с крякозябрами. Что пробовала: 1) Перехват функции GetACP - с помощью сплайсинга. Запускаю программу под отладчиком, нахожу адрес процедуры GetACP - в начало этого кода ставлю jmp на свою, правильную функцию, которая возвращает требуемое значение 1251. Результат такой - всё хорошо, функция GetACP теперь возвращает правильное значение 1251 (вместо 65001) - однако, в программе вообще ничего не меняется. Всё равно всё отображается с крякозябрами. 2) Пыталась использовать недокументированную функцию SetCPGlobal(1251); После этого GetACP возвращает правильное значение. Проблема только в том, что работает эта недокументированная функция только на Windows XP - но на XP и без неё всё нормально работает. На Windows 7 и Windows 10 - при попытке использовать данную функцию - при запуске программы выходит сообщение Точка входа в процедуру SetCPGlobal не найдена в библиотеке Kernel32.dll и программа завершает свою работу 3) Пыталась найти - где же функция GetACP получает значение 65001 - чтобы прописать по этому адресу 1251 (как говорят на форумах, это адрес переменной gAnsiCodePage в модуле KernelBase.dll). Нашла адрес - область, откуда берётся это значение, там как раз записано значение 65001. Перезаписываю данную область памяти в значение 1251 с помощью ассемблерной вставки - после этого функция GetACP возвращает значение 1251. На Windows 7: .............................. MyGetACP := GetProcAddressInDll('KernelBase.dll', 'GetACP'); z := ReadMemoryDword(1+integer(Addr(MyGetACP))); WriteMemoryDword(z, 1251); //rewrite value of variable - where keeping GetACP ShowMessage('GetACP: '+inttostr(GetACP)) //на Windows 7 работает .............................. На Windows 10 же (где и требуется решить вопрос с крякозябрами) получается совсем по-другому. Как только пытаюсь перезаписать значение данной ячейки в 1251 - тут же появляется ошибка Exception EAccessViolation in module KernelBase.dll at 000F69ED. Access violation at address 76D269ED in module 'KernelBase.dll'. Read of address 00000002. и программа вылетает. При этом перезапись ячейки памяти делаю как полагается - перед перезаписью устанавливаю признак PAGE_EXECUTE_READWRITE для перезаписываемой области памяти: VirtualProtect(pointer(a), 16, PAGE_EXECUTE_READWRITE, OldProtect) Пробовала в качестве экспериментов записывать в эту ячейку значения 1252, 65001 (то есть исходное значение) и даже 9999 - всё отрабатывает нормально (но потом в ходе работы программы возникают ошибки). Если же записать 1251 - программа вылетает сразу. Возникает вопрос - что делать, чтобы программа работала на Windows 10 без крякозябр вместо русских букв при включенной опции "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире". Варианты перейти с Delphi 7 на другую, более новую версию - не предлагать (очень много старого кода придётся переписывать, который при переписывании может начать глючить и т. д.) Варианты с TntComponents и JEDI тоже не подойдут - т. к. программа содержит гигантское количество старого программного кода - где используются стандартные компоненты TLabel, TButton, TEdit - даже если новый код писать на JEDI - надо чтобы старый код и старые формы работали без крякозябр. Как правильно перехватить GetACP, чтобы она всегда возвращала значение 1251? Как заставить программу работать без крякозябр? Дело ведь в GetACP - туда надо копать или в чем можем быть дело? С уважением, Сидорова А. П. |
6 апр 21, 11:14 [22304955] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2792 |
Анна Петровна, https://github.com/MahdiSafsafi/DDetours |
6 апр 21, 11:22 [22304957] Ответить | Цитировать Сообщить модератору |
delphinotes Member Откуда: Санкт-Петербург Сообщений: 379 |
Анна Петровна, Ух, столько упорства, а обновиться на юникодную версию делфи - не предлагать? Там не так уж и сложно, на самом деле, тем более, если в основном компоненты стандартные. Более того, в MS конечно молодцы, стараются обратную совместимость поддерживать по максимуму, но кто знает, что там будет в будущем. P.S.: Указанная галка у меня _по_умолчанию_ выключена, сама не включалась. P.S.2: может лучше в MS куда-нить и написать? |
6 апр 21, 11:26 [22304958] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
А чем шрифт Arial лучше в плане кодировок чем MS Sans Serif ? |
6 апр 21, 12:05 [22304973] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
06.04.2021 12:05, avp_ пишет: > А чем шрифт Arial лучше в плане кодировок чем MS Sans Serif ? MS Sans Serif - изначально растровый. в зависимости от версии Win и настроек FontSubstitutes в реестре, он может мапироваться на TTF шрифт Microsoft Sans Serif, но обычно нет. Posted via ActualForum NNTP Server 1.5 |
6 апр 21, 12:09 [22304976] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
avp_, да, Arial - однозначно лучше, с MS Sans Serif крякозябры будут во многих случаях, когда их не будет с Arial. Программно отключать данную опцию в системе совсем не проблема. Пишем REG-файл, пишем пользователю, что нужно запустить этот файл, перезагрузить компьютер - но это всё лишние действия и неудобства - в этом и проблема. И вообще это всё костыли, хотелось бы нормального решения проблемы. Переход с Delphi 7 на Delphi 2009 - как я понимаю, может решить вопрос (это самая ранняя версия Delphi с поддержкой Юникода и по идее, переписывать придётся меньше, чем если сразу переходить на Delphi XE 10). Но вопрос-то как раз именно в том - как решить проблему, оставаясь в рамках Delphi 7 (до этого подобные проблемы удавалось решать в рамках Delphi 7). Потому что переход на новую версию Delphi (даже 2009) - это всё равно необходимость переписывания кода, глюки, недовольства пользователей, бессонные ночи и нервозность во время отпусков. |
6 апр 21, 12:27 [22304994] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Наверно, можно перехватывать SetWindowText и в случае acp=utf8 конвертировать строки на лету. А режим совместимости не помогает? |
6 апр 21, 12:29 [22304998] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
1 D2009 была очень сырая и сама по себе содержала кучу ошибок. 2. Переход с 2009 на следующие версии практически незаметен (за исключением багов, которые появляются в конкретной версии Delphi) Поэтому если надумаете переходить на юникодную версию - переходите сразу на последнюю |
||||||||
6 апр 21, 12:43 [22305005] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
Тынц
|
||
6 апр 21, 12:49 [22305007] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
_Vasilisk_, Я так понимаю, проблема не при самой перезаписи возникает, а уже после. Например, при выводе ShowMessage - когда идут обращения к изменённой функции. В Windows 7 таким образом всё работает нормально, но в Windows 10 глючит. С переходом на Delphi XE8 возникло множество проблем (были попытки еще в 2017 году) - собственно, поэтому и пришлось от этого отказаться. В конце концов, удалось скомпилировать на Delphi XE8 - программа запустилась - но с таким количеством глюков, что я испугалась и решила остаться на D7. На Delphi XE10 - даже скомпилировать не удалось. Поэтому и думаю - попытаться с Delphi 2009. Если же она очень глючная - возможно, стоит попробовать 2010 или XE/XE2. |
6 апр 21, 13:14 [22305023] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
У меня тоже большой проект на древнем C++ Builder, перевод на свежее уже практически нереален. |
6 апр 21, 13:38 [22305031] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Интересно, а если в этом режиме внутри программы применять конвертацию в utf8 - сработает? Edit1.Text := AnsiToUtf8('блабла') |
6 апр 21, 14:52 [22305075] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Fr0sT-Brutal, не знаю - сработает или нет - но думаю, определённо глюков будет еще больше чем при переходе на Delphi 2009/2010. Так как программа анализирует значения, которые вводятся в Edit и работает с ними как с обычными 1-байтовыми строками. хотелось бы чтобы значение в Text не менялось, менялся чтобы только алгоритм отрисовки - например, перехватывать метод отрисовки, конвертировать строку в UTF-8 и выводить как UTF-8. Но тут проблема тогда ещё - что делать в режиме редактирования строки - какие символы и как отрисовывать, как отрисовывать курсор и т. д. |
6 апр 21, 16:50 [22305123] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Замените их уже на TNT Controls и не парьте моск. Posted via ActualForum NNTP Server 1.5 |
6 апр 21, 18:19 [22305156] Ответить | Цитировать Сообщить модератору |
delphinotes Member Откуда: Санкт-Петербург Сообщений: 379 |
Конвертация большого проекта D2007 в юникод и переход на новую версию Delphi |
6 апр 21, 19:25 [22305179] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
Если какая-то программа попытается поменять мне системные настройки, то моментально и она и её аффтор пойдут в эротическое пешее путешествие. Была помнится тулзня от мелкомягких AppLocale. С её помощью можно запускать приложение в нужной для неё локали |
6 апр 21, 22:15 [22305202] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
white_nigger, А я уже подумываю над этим - чтобы так сделать. Но боюсь - если при получении GetACP=65001 требовать запуск от имени администратора, патчить реестр ветку HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage и перезапускать компьютер после этого - программа может попасть в базы антивирусов. Как минимум, надо спрашивать пользователя перед выполнением данных действий. Например, выдавать сообщение, что обнаружены неверные языковые настройки - изменить да/нет, перед перезапуском компьютера тоже спросить. Но проблема в том -что если пользователю предоставлять такой выбор - пользователь ведь может отказаться и выбрать "Нет", увидеть страшные крякозябры и вместо перезапуска компьютера просто отказаться от программы. Поэтому как ни крути - хоть выполняй данные действия (патчить реестр и перезапускать компьютер), не спрашивая пользователя - хоть спрашивай - любой из этих вариантов так или иначе ведёт к потере части пользователей ... Поэтому да - были бы интересны решения без изменения системных настроек. Или с изменением данных настроек только для запускаемой программы. Например, запускать программу специальным bat-файлом, в котором перед запуском самой программы что-то прописано для задания правильных языковых настроек конкретно для запускаемой программы ... |
6 апр 21, 23:18 [22305220] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
|
||||
6 апр 21, 23:40 [22305222] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
white_nigger, Увы, AppLocale - не вариант под Windows 10. Под его аналогом NTLEA программа запускается, все русские надписи отображаются как нужно. Но ввод русских букв в Edit и в другие элементы невозможен. Locale.Emulator.2.4.1.0 - программа запускается, русские буквы точно также как в NTLEA отображаются корректно. Но при вводе русских букв в Edit или в Memo - вводятся крякозябры. SBAppLocale - вообще толком не работает. |
7 апр 21, 00:11 [22305228] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Почему бы не попробовать? По идее, RTL фиолетово, что там за строки, ansi или utf8 - главное, чтобы не utf16 (иначе будут проблемы с #0). А контролы крутятся внутри winapi, у них там utf16. В/из utf8 перегоняется при вызовах S/GetWindowTextA, как я понимаю. |
||||
7 апр 21, 10:36 [22305294] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Не понятно почему просто не сделали возможность каждому процессу иметь свою собственную ANSI кодировку. Добавили бы функцию SetACP и всё. |
7 апр 21, 12:34 [22305357] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Видимо, сложнее, да и не нужно особо никому. ACP должны умереть. |
||||
7 апр 21, 12:41 [22305362] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
К чему такой фашизм? Горы софта написано который работает и делает своё дело. |
||||
7 апр 21, 13:50 [22305401] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
С переходом на Delphi 2010 возникают проблемы. В программе много хаков, быдлокода и говнокода, который на D2010 нормально не переносится. Как пример, в каждом модуле в секции USES используется конструкция USES {$I AllVcl.pas}; В AllVcl.pas прописано DBTables, ComCtrls, DBCtrls, ComObj, IBTable, Mask, OleCtrls, SHDocVw, Windows, tlhelp32, Buttons, ImgList, ActnList, Classes, Graphics, Controls, Forms, Dialogs, IBStoredProc, StdCtrls, DB, IBDatabase, IBCustomDataSet, IBQuery, Grids, DBGrids, Menus, ExtCtrls, TeeProcs, TeEngine, Chart, shellapi, Registry, ShlObj, ADODB, IBSQL, ActiveX, При компиляции проекта Delphi среда зачнем-то добавляет свой код, получается в итоге лажа uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; USES {$I AllVcl.pas}; и программа не компилируется. Зачем Delphi 2010 добавляет свою секцию USES перед тем что уже прописано - непонятно - ведь там в AllVcl.pas и так уже прописаны все необходимые модули. Delphi 7 такую ерунду не делал. Как отучить Delphi 2010 модифицировать файл с кодом при сохранении (Save) и перед запуском (F9)? Что же теперь - вместо USES {$I AllVcl.pas}; надо писать DBTables, ComCtrls, DBCtrls, ComObj, IBTable, Mask, OleCtrls, SHDocVw, Windows, tlhelp32, Buttons, ImgList, ActnList, Classes, Graphics, Controls, Forms, Dialogs, IBStoredProc, StdCtrls, DB, IBDatabase, IBCustomDataSet, IBQuery, Grids, DBGrids, Menus, ExtCtrls, TeeProcs, TeEngine, Chart, shellapi, Registry, ShlObj, ADODB, IBSQL, ActiveX, в каждом модуле и переписывать все старые модули? |
7 апр 21, 13:56 [22305407] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Ну а по поводу хаков - в проекте в папке с программой лежат модифицированные DBGrids.pas Forms.pas IB.pas и другие модули VCL А в Delphi 2010 - проблема такая, что модули VCL идут вообще без исходного кода. Так что непонятно как их модифицировать чтобы сохранить все хаки,сделанные в Delphi 7. |
7 апр 21, 13:58 [22305408] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Fr0sT-Brutal, Так нужны ведь. Мне например, нужны. И вообще есть горы софта, которые работают без поддержки Юникода. Переписывание софта или переход на другие версии с поддержкой УТФ это в любом случае новые баги, недовольства пользователей и прочее. Не говоря про то, что есть куча старого софта, который заброшен и который вообще некому переписывать. |
7 апр 21, 14:00 [22305410] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Этот старый софт не пытается говорить по-русски с французами. Серьёзно повторяю предложение задействовать TNT Unicode Controls и не парить моск. Posted via ActualForum NNTP Server 1.5 |
7 апр 21, 14:05 [22305413] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
К тому, что это гемор и пережиток темного прошлого. Аналоговое ТВ сдохло, и кодовые страницы должны сдохнуть тоже. |
||||||||
7 апр 21, 14:24 [22305420] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Dimitry Sibiryakov, Так TNT надо было использовать с самого начала а в идеале и писать на Delphi 2010 сначала, а не на 7 ... А теперь нереально на него переписать десятки тысяч строк кода ... |
7 апр 21, 14:42 [22305432] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
на ТНТ перейти гораздо проще, чем на новые версии Delphi. Posted via ActualForum NNTP Server 1.5 |
7 апр 21, 14:45 [22305435] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Fr0sT-Brutal, "Наверно, можно перехватывать SetWindowText и в случае acp=utf8 конвертировать строки на лету" - как ни странно - но похоже, что сработало. Пожалуй, использую это, чтобы временно решить проблему сейчас. Но всё равно буду готовить софт к переходу на Delphi 2010 (он юникодный, с него вероятно будет проще перейти на Delphi XE10 в дальнейшем). Delphi 7 рано или поздно умрёт, наверное лучше переходить на D2010, чем на TntComponents (скорее всего и то и то потребует сопоставимо усилий). |
7 апр 21, 14:46 [22305437] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Мимопроходящий, а что делать со старым кодом, который работает с кучей Edits, Grids, DBGrids итд? |
7 апр 21, 14:47 [22305438] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Назвать новые контролы так же как старые, чтобы имеющийся код ничего не заметил?.. Posted via ActualForum NNTP Server 1.5 |
||
7 апр 21, 14:50 [22305440] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Я бы для начала выяснил причину кракозябров в D7. На каком конкретно шаге "не так". Может, там просто всё решается. |
7 апр 21, 15:21 [22305458] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1299 |
|
||||
7 апр 21, 15:32 [22305466] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2792 |
Тут, по-моему, выход только один: на текущий момент предлагать пользователю отключать эту настройку, которая мешает работать программе, и параллельно начать писать новую версию программы без быдлокода и на современной версии (возможно даже не дельфи, но это по желанию). Иначе в один далеко не прекрасный момент вы столкнётесь с чем-то, что уже не сможете обойти и выхода у вас не будет. |
7 апр 21, 15:47 [22305473] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Кстати, помогло создание обёрток в виде, представленном ниже. Это работает с Buttons, но не работает с Edits. type TUtfButton=class(TButton) public procedure SetCaption(s: string); function GetCaption: string; property Caption: string read GetCaption write SetCaption; end; TButton=class(TUtfButton) end; ...................... var mode: integer=0; procedure TUtfButton.SetCaption(s: string); begin if mode=0 then inherited Caption := s else inherited Caption := AnsiToUtf8(s); end; function TUtfButton.GetCaption: string; begin if mode=0 then result := inherited Caption else result := Utf8ToAnsi(inherited Caption); end; .................... BEGIN if GetACP=65001 then mode:=1; END. Главная проблема с Edits - всё работает нормально (даже без обёрток) - если работать с ними с помощью программного кода. Если же стартовое значение Edit было присвоено в свойствах формы (dfm) - в этом случае загружаются крякозябры и расшифровать их уже невозможно. Ч так понимаю, что-то нужно делать в методе F.ReadComponent(Self) чтобы Edits загружались из dfm в верной кодировке ... |
7 апр 21, 15:56 [22305485] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2792 |
Тупо переделать всё на программную инициализацию не предлагать?.. |
||||
7 апр 21, 16:11 [22305495] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
Анна Петровна, Перехватывать WM_SETTEXT/WM_GETTEXT. |
7 апр 21, 16:13 [22305497] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Самый простой и топорный способ - позаменять во всех dfm TEdit => TUtf8Edit. Ну и TUtf8Edit полноценно зарегистрировать в среде как компонент |
||||
7 апр 21, 16:21 [22305510] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Так наверняка при описанном режиме *A функции перегоняются в *W предполагая, что на входе utf8. Конечно, когда там на самом деле 1251, получается лажа. |
||||
7 апр 21, 16:25 [22305518] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
alekcvp, Походу - решается вопрос без перехода на программную реализацию (перейти нереально - там десятки тысяч строк кода). При создании формы загружаем из dfm копию компонента - она загрузится в память в ANSI без всяких там перекодировок UTF8 и UTF16. А дальше уже - присваиваем компонентам формы значения из копии - перекодируя с помощью AnsiToUtf8. В этом случае получается то же самое - как и в случае программной реализации. Присваиваем значения точно также программно - только считывая их из копии DFM. |
7 апр 21, 16:36 [22305524] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Fr0sT-Brutal, Там всё гораздо хуже. В dfm похоже, что всё хранится в UTF-16, а при чтении из свойства Text компонента - в UTF-8. И при загрузке из dfm русские буквы как-то хитро перекодируются - причём с потерей данных. Например, в Edit был в dfm текст "Песик", 5 символов (не смейтесь, тестировала), а при чтении свойства Edit из свойства Text получалось 6-символьные крякозябры. Записала значение в файл. Открываю в FAR, а там в кодировке 65001 слово "Пес". То есть часть информации потерялась. Поэтому - либо значения Edits не хранить в dfm - либо грузить копию dfm при создании формы - перекодируя как нужно в UTF-8. |
7 апр 21, 16:42 [22305532] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
Примерно так: type TCustomFormStore = class(TComponent) protected procedure Loaded; override; end; implementation procedure TCustomFormStore.Loaded; begin inherited; if not (csDesigning in ComponentState) and Assigned(Owner) and (Owner is TForm) then begin { перебираем компоненты и конвертируем проперти } end; end; |
||||
7 апр 21, 16:43 [22305533] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Мимопроходящий, Да, именно об этом и речь - только у Вас возможно красивее и проще. Способ, в принципе, рабочий. Осталось написанный некрасивый код причесать и сделать - чтобы всё было в виде одного модуля. При подключении которого в конце секции USES - чтобы всё работало как раньше, как ни в чём не бывало. Без перехвата WM_SETTEXT/WM_GETTEXT вполне можно обойтись - достаточно переопределить свойства Caption, Text у объектов - чтобы при обращении к свойству Text вызывался свой код, который уж как надо всё перекодирует. |
7 апр 21, 16:51 [22305539] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Мимопроходящий, Вы имеете ввиду - в вашем варианте вместо моего не придётся грузить копию компонента из dfm, а можно сразу поправить нужные свойства? И присвоить правильные свойства можно будет ещё до того, как они будут испорчены с потерей информации? |
7 апр 21, 16:56 [22305545] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
метод Loaded вызывается сразу после того, как все компоненты формы загрузили свои свойства из dfm-потока. в этот момент вы можете их все скопом перекодировать по своему усмотрению. |
||||
7 апр 21, 17:01 [22305549] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Текстовые свойства Delphi 7 хранит в Unicode. Т.е. тот же Caption у TButton читается таким методом:function TReader.ReadWideString: WideString; var L: Integer; Temp: UTF8String; begin if NextValue in [vaString, vaLString] then Result := ReadString else begin L := 0; case ReadValue of vaWString: begin Read(L, SizeOf(Integer)); SetLength(Result, L); Read(Pointer(Result)^, L * 2); end; vaUTF8String: begin Read(L, SizeOf(Integer)); SetLength(Temp, L); Read(Pointer(Temp)^, L); Result := Utf8Decode(Temp); end; else PropValueError; end; end; end; Здесь проблем нет. Далее, прочитанный WideString "Песик" конвертируется в AnsiString вызовом _LStrFromWStr / _LStrFromPWCharLen / CharFromWChar, что в итоге сводится к вызову: Result := WideCharToMultiByte(DefaultUserCodePage, 0, WCharSource, SrcChars, CharDest, DestBytes, nil, nil); где DefaultUserCodePage - глобальная переменная, по умолчанию равная 3 (CP_THREAD_ACP). Т.е. WideString "Песик" корректно преобразуется в UTF-8 "Песик" (10 символов UTF-8). Ну и в дальнейшем эта AnsiString будет передана в *A функции WinAPI, которые тоже корректно должны её опознать. Так что не, что-то где-то другое косячит. |
7 апр 21, 17:40 [22305574] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Мимопроходящий, Да, в Loaded можно перекодировать компоненты формы (кнопки и т. д.). Однако каким-то странным образом - в Loaded невозможен доступ к свойствам самой формы. И даже в OnCreate невозможно! То есть заголовок формы в OnCreate и в Loaded перекодировать не получится, а в Activate будет уже поздно. Можно, конечно, в случае GetACP=65001 просто тупо сделать заголовки всех форм пустыми. Но всё же интересно - почему в OnCreate и в Loaded нет доступа (даже на чтение) к свойствам самой формы. Пример кода: unit Unit1; INTERFACE USES Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormActivate(Sender: TObject); private procedure Loaded; override; end; var Form1: TForm1; IMPLEMENTATION {$R *.dfm} //реальное значение Visible: 1 (видимая) procedure TForm1.FormCreate(Sender: TObject); begin ShowMessage('FormCreate: '+inttostr(ord(self.Visible))); //0 - неправильное значение, должно быть 1 end; procedure TForm1.FormActivate(Sender: TObject); begin ShowMessage('FormActivate: '+inttostr(ord(self.Visible))); //1 - правильное значение, но уже поздно, кодировка испорчена end; procedure TForm1.Loaded; begin inherited Loaded; ShowMessage('Loaded: '+inttostr(ord(self.Visible))); //0 - неправильное значение, должно быть 1 end; END. Сообщение было отредактировано: 7 апр 21, 17:36 |
7 апр 21, 17:43 [22305580] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Только что проверил: собрал в Delphi 7 приложение с Button1.Caption = "Песик" и запустил на Win10 c GetACP = UTF-8 - всё прекрасно показалось, как и ожидалось. |
7 апр 21, 17:51 [22305590] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Вот что не сработает - так это константы в коде:
ShowMessage('Песик');
здесь 'Песик' хранится как AnsiString со всеми вытекающими... |
7 апр 21, 17:52 [22305592] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Теперь осталось понять какой именно из навороченных аффтаршей костылей усекает значение по байтам вместо символов. Posted via ActualForum NNTP Server 1.5 |
||
7 апр 21, 17:55 [22305595] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
GunSmoker, В Button - да, в этом случае всё нормально отображается. А если задать "Пёсик" в Edit (в свойствах формы) - тогда Edit отображается с крякозябрами. Как оказывается, там 6 символов вместо 5. Если записать значение Edit.Text в файл - то файл будет 6 байт, при открытии в FAR в кодировке 65001 покажет "Пёс". Сообщение было отредактировано: 7 апр 21, 17:59 |
7 апр 21, 18:05 [22305602] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
В свойствах на форме задаём (Delphi 7): Edit1.Text = Пёсик object Edit1: TEdit Left = 8 Top = 16 Width = 121 Height = 21 TabOrder = 0 Text = #1055#1105#1089#1080#1082 end Далее запускаем программу, в FormActivate выполняем System.Assign(f, 'c:\temp\15.txt'); System.Rewrite(f); System.Write(f, Edit1.Text); System.Close(f); каким-то магическим образом в 15.txt оказывается 6 символов вместо 5: #208 #159 #209 #145 #209 #129 Если в FAR установить кодировку UTF-8 то будет Пёс Но вопрос этот решаемый. Как я понимаю - надо перекодировать значение до вызова OnActivate тогда всё будет нормально, без потери данных. |
7 апр 21, 18:13 [22305608] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
GunSmoker, ShowMessage('Песик'); - ну тут как раз всё просто - перекодируем в UTF-8 и выводим. Переписывать код не придется - достаточно в конце секции USES подключить свой модуль с правильным ShowMessage - который перекодирует данные перед выводом. Или отказываемся от ShowMessage, используем MessageBoxW. |
7 апр 21, 18:18 [22305613] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Магии никакой нет. Какой-то из ваших "перехватчиков" свойств и/или сообщений обрезал строку по пути. Posted via ActualForum NNTP Server 1.5 |
||
7 апр 21, 18:22 [22305616] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Dimitry Sibiryakov, Такое поведение - вообще если создать новый чистый проект без каких либо перехватчиков. С Button всё нормально как и пишет GunSmoker. А с Edit как-то по-другому получается, значение портится, вместо 5 байт получается 6 и "Пёсик" обрезается до "Пёс" - правда, становится 6 байт вместо 5. DFM: ################################## object Form1: TForm1 Left = 445 Top = 277 Width = 265 Height = 214 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Edit1: TEdit Left = 8 Top = 16 Width = 121 Height = 21 TabOrder = 0 Text = #1055#1105#1089#1080#1082 end object Button1: TButton Left = 8 Top = 40 Width = 121 Height = 25 Caption = #1055#1105#1089#1080#1082 TabOrder = 1 OnClick = Button1Click end end ################################## Unit1: ################################## unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var f: System.Text; begin System.Assign(f, 'c:\temp\15.txt'); //тут будет "Пёс" из 6 байт если запускать на Win-10 с обсуждаемой опцией System.Rewrite(f); System.Write(f, Edit1.Text); System.Close(f); end; end. ################################## |
7 апр 21, 18:31 [22305626] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
В случае с TEdit.Text свойство Delphi хранит как AnsiString и его чтение выполняется функцией:function TReader.ReadString: string; var L: Integer; begin if NextValue in [vaWString, vaUTF8String] then Result := ReadWideString else begin L := 0; case ReadValue of vaString: Read(L, SizeOf(Byte)); vaLString: Read(L, SizeOf(Integer)); else PropValueError; end; SetLength(Result, L); Read(Pointer(Result)^, L); end; end; Разумеется, это работать не будет. Интересно, что и Caption у TButton, и Text у TEdit - это свойства TControl типа TCaption. Разницы между ними я не вижу. |
7 апр 21, 18:52 [22305637] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Т.е. вы готовы весь код перелопатить, понавставлять всюду костылей? Это же ведь не только ShowMessage, а вообще любое использование строковых не-ASCII литералов в коде. Я вот из личного опыта скажу: перейти на Unicode это в несколько раз проще, чем расставлять везде костыли. |
||||
7 апр 21, 18:54 [22305639] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Давайте просуммируем: 1. Чтобы программа могла работать с GetACP = UTF8, в идеале исходники её строк должны быть UTF8 или UTF16. В не идеале - ANSI + перекодировка. В последнем случае придётся добавлять код перекодировки. В некоторых случаях (типа загрузки формы или 3rd party code) - он может быть весьма нетривиальным. 2. Изменить GetACP только для своей программы "чисто" не получится. Это глобальная настройка системы - не зря она просит полный перезапуск после её изменения. Хотя вот тут описывается настройка манифеста - надо проверить. 3. Можете попробовать хаки типа Microsoft AppLocale или Locale Emulator. Но надо понимать, что это хаки. Программа, использующая их, может перестать работать в будущем. 4. Менять глобальную настройку (опцию системы) для решения локальной проблемы (ваши проблемы с кодировкой) - путь в ад. Итого, я вижу два варианта нормального решения: 1. Обновиться на Unicode. 2. При установке проверять, если GetACP = UTF-8, выводить предупреждение пользователю, что программа работать так не сможет и предложить это исправить. Исправлять без согласия пользователя - низзя. |
7 апр 21, 19:16 [22305649] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Что разве MS сделали по дефлоту включенным UTF-8 ? |
7 апр 21, 20:22 [22305676] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
В принципе, Д7 можно подсунуть исходники в utf8. Ей должно быть пофиг на содержимое литералов. Обратная совместимость с ansi софтом - имхо, чуть ли не главная фишка данной кодировки
Сообщение было отредактировано: 7 апр 21, 20:32 |
7 апр 21, 20:38 [22305684] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1299 |
+ |
||||
7 апр 21, 21:05 [22305696] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
Могу добавить, что "десятки тысяч строк кода" - это копейки. В любой серьёзной библиотеке их сотни тысяч, а то и миллионы. |
7 апр 21, 22:34 [22305714] Ответить | Цитировать Сообщить модератору |
crossa Member Откуда: Сообщений: 90 |
Если опция включена в региональных настройках Windows, множество старого софта перестанет нормально работать. Рекомендую добавить информацию в раздел "Часто задаваемые вопросы", если есть такой на сайте Вашего программного продукта (как сделано здесь, например). Это и будет разумным решением проблемы (и авторам других старых программ поможет). А самовольно менять системные настройки чужой операционной системы - что-то как-то не есть хорошо. P.S. В сети встречаются сообщения о проблемах с включенной опцией: "Problem: ArcGIS Pro crashes or experiences character encoding issues when the ‘Beta: Use Unicode UTF-8 for worldwide language support’ region setting is enabled on Windows 10". Сообщение было отредактировано: 8 апр 21, 01:50 |
8 апр 21, 01:52 [22305756] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
GunSmoker, >Я вот из личного опыта скажу: перейти на Unicode это в несколько раз проще, чем расставлять везде костыли. Да - правильнее всего, конечно, будет перейтти на D2010. Но и в пользу костылей есть некоторые аргументы. К счастью, не у всех пользователей включена по умолчанию опция "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире" поэтому вставка костылей не повлияет на стабильность работы отлаженного ПО у 90% пользователей - у кого эта опция по умолчанию отключена ничего не изменится и всё останется как было. А у тех, у кого опция включена - да, будут ловить баги (но постепенно, с расстановкой костылей количество багов будет уменьшаться). А вот при переходе на Delphi 2010 изменения затронут сразу 100% пользователей. И придется вести две версии - стабильную на D7 и тестовую на D2010. Поэтому и пугает так переход на D2010. Хотя я понимаю, что это всё равно неизбежно - и чем дальше тем труднее будет перейти, тк количество кода, хаков и прочего в программе растёт, а у D7 и так понятно, что нет будущего (например, опасаюсь, что рано или поздно Microsoft вообще откажется от поддержки 32-битного кода как недавно сделала Apple и это поставит окончательную точку в использовании D7). Всякие TntComponents использовать не хочется - т. к. опасаюсь, что это ещё больше затруднит слезание с D7 в будущем. Поэтому, наверное, расставить временно костыли и готовить проект к переходу на D2010 раз уже такие сложности с переходом сразу на XE8/XE10. Надеюсь, D2010 - правильный выбор - т. к. это наиболее ранняя из версий с поддержкой Unicode и разницы с D7 у неё должно быть меньше, чем в случае скажем с XE2, XE8 или XE10. Есть, конечно еще D2009 - но судя по всему, D2010 это та же 2009 только меньше глюков. А вы не знаете случайно - как запретить компилятору в редакторе кода портить секцию USES? Если в начале каждого модуля формы уже прописано USES {$I AllVcl.pas} а в файле AllVcl.pas - список всех модулей, которые могут потребоваться и незачем туда что-то добавлять но при сохранении и при запуске программы D2010 (кстати, XE2 и XE8 тоже эти страдают) зачем-то добавляет Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; и получается каша вида uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; USES {$I AllVcl.pas} которая разумеется, не компилируется. D7 так не делает - а при разработке проекта не задумывалась что потом такие проблемы с переходом на новые версии Delphi возникнут. Неужели в новых версиях Delphi нельзя делать USES сразу всех нужных модулей, подгружая список из файла, а необходимо через запятую перечислять в USES каждого модуля? Но ведь там 10 строк в списке модулей может быть и это очень неудобно - например, если потребуется какой-либо модуль добавить в USES сразу всех форм программы ... |
8 апр 21, 02:16 [22305760] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Боюсь, что сделают рано или поздно. Более того, могут подобно Apple вообще отказаться от поддержки 32-разрядного кода. Как подумаю об этом, холодный пот пробирает ... |
||||
8 апр 21, 02:19 [22305761] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
XE2 не сильно отличается, зато поновее. Хотя и на 2010 сидел долгое время, тоже неплохая версия.
Так добавь в модули форм всю стандартную требуху, которую среда хочет (uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs), а потом следующей строкой вставляй свои добавочные USES {$I AllVcl.pas}. Должно сработать. Ну и в целом эта практика какая-то нехорошая. Если требуется добавлять модуль - значит, в коде что-то начинает его использовать, значит, все равно код меняется. |
||||||
8 апр 21, 10:32 [22305844] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Так проблема в том, что среда добавляет требуху - но не всё, что у меня прописано в AllVcl.pas, а только ту требуху, которую захочет, в зависимости от того, какие компоненты на данной форме. А в у меня AllVcl.pas прописаны все модули VCL, которые могут потребоваться (а еще IB.pas, shellapi.pas, ComObj.pas и прочее). И после AllVcl.pas у меня следом идёт MyUnits.pas - то есть USES {$I AllVcl.pas}, {$I MyUnits.pas}; в котором перечислены мои модули - функционал которых во многом базируется на AllVcl.pas. И если вместо AllVcl.pas использовать требуху, которую вставляет Delphi - мои модули перестанут работать - если Delphi вставит не всё, что нужно - а он как правило вставит не всё - а только то, что ему нужно. И ещё ситуация - если в AllVcl.pas надо будет добавить новый модуль - это делается простой правкой файла AllVcl.pas - а не надо будет лазить по всем модулям и добавлять. Проблема в том, что если разрешить вставлять Delphi требуху - вроде uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; а потом дописывать чтобы было uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, {$I AllVcl.pas}, {$I MyUnits.pas}; то при компиляции Delphi будет ругаться identifier redeclared. То есть требуха, которую добавляет Delphi - пересекается с той, что у меня в AllVcl.pas, а AllVcl.pas убирать нельзя, так как на нем базируется MyUnits.pas. В этом и проблема. Если бы D2010 не трогал секцию USES как D7 всё было бы нормально. Сообщение было отредактировано: 8 апр 21, 12:00 |
||||
8 апр 21, 12:06 [22305886] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
На 2010 в комплекте есть исходники VCL? Очень нужно чтобы перенести костыли с 7 на 2010. У меня в комплекте с 2010 только dcu. Подозреваю, Embarcadero в 2010 закрыла исходный код VCL, распространяя только DCU. В XE2, XE8, XE10 - кстати исходники есть, как и в 7. А вот в 2010 нет. Вот теперь и думаю, или это целенаправленная политика Embarcadero в 2010 (от которой они потом отказались) или это просто у меня кривая 2010. Хочется именно 2010, а не XE2 - чтобы изменения были минимальными, а в XE2 уже добавились новые фишки в сравнении с 2010 - вроде USES Vcl.Classes вместо USES Classes и прочее - что создаст дополнительный геморрой при переходе - а переход на Unicode сам по себе уже и так не сахар зачем еще дополнительный геморрой. А уж потом - обжившись на 2010 - переходить сразу на XE10. |
||||
8 апр 21, 12:14 [22305887] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
[quot GunSmoker#22305639]
Не так уж и много костылей получается. Т. к. в конце каждого модуля у меня подключен список моих модулей {$I MyUnits.pas} Там можно и прописать новый вариант ShowMessage и прочего, что перекроет стандартные методы. Это удобно с одной стороны - а с другой стороны - мешает переходу на новые версии Delphi. |
||||
8 апр 21, 12:18 [22305888] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Откажутся вряд ли, но вот усложнить жизнь всякими мелкими пакостями вполне смогут. Пока стоит сделать юзеру предупреждение при старте программы, что кодировка отличается от 1251 и потребовать её измерения. |
||||
8 апр 21, 12:27 [22305894] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
[quot avp_#22305894]
Разумеется, это уже сделала - причем программа задаёт вопрос пользователю сначала об изменении языковых настроек, а потом о перезагрузке компьютера, а не просто меняет системные настройки и следом перезагружает систему. Был соблазн сделать, чтобы программа просто меняла системные настройки как нужно и потом перезагружала компьютер - но в этом случае опасаюсь, что программа по поведению будет похожа на вредоносную и соответственно, имеет шанс попасть в базы антивирусов. И вообще это выглядит как серпом по одному месту. Сейчас занимаюсь подготовкой костылей - чтобы всё приемлемо пусть хотя бы и с некоторыми багами (а не как сейчас - сплошные крякозябры и невозможность работы) работало и при включенной опции "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире" на случай если пользователь откажется что-то менять. И разумеется, хочу перейти на Delphi 2010. Но вот мои USES {$I AllVcl.pas}, {$I MyUnits.pas}; в каждом модуле очень этому мешают. |
||||
8 апр 21, 12:53 [22305909] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Ну да - могут сделать какие-нибудь пакости - например, сделать чтобы по умолчанию работали только 64-разрядные программы. А для возможности работы 32-разрядных чтобы было необходимо включить какую-нибудь хитрую галочку в недрах системы и перезагрузить компьютер, разумеется. Впрочем, с переходом на юникодную версию Delphi подобные пакости будут не страшны. Тк с юникодной 2010 перейти хотя бы на XE2 (минимальная что поддерживает 64-бит) думаю не составит большого труда. Главное уйти с неюникодного D7. |
||||
8 апр 21, 12:57 [22305916] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
"Search-and-Replace in Files" решит эту проблему быстрее, чем вы прочитаете это сообщение. Так что мешают отнюдь не они. Posted via ActualForum NNTP Server 1.5 |
||
8 апр 21, 12:58 [22305919] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Dimitry Sibiryakov, При переходе на новую версию Delphi неизбежны баги - поэтому нужно будет параллельно вести две версии на D7 и D2010. Так что тупо Search и Replace не вариант. Надо переписывать проект - чтобы он компилировался в D7 - но при этом без изменений также компилировался в D2010 (только потом, когда сборка будет стабильной на 2010 можно будет отказаться от D7 совсем). Ну или изменения должны быть такие, чтобы нужные куски кода переключались специальной директивой - например, {$IFDEF Delphi2010} ................. {$ELSE} ................. {$ENDIF} Заменять в каждом модуле {$I AllVcl.pas} на кучу мусора в виде списка модулей в нём - конечно, не проблема (и даже не Search&REplace, а скриптом на AutoIt или на том же Delphi) - но как-то не представляется это правильным и красивым решением. Сообщение было отредактировано: 8 апр 21, 13:07 |
8 апр 21, 13:13 [22305929] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Зачем делать самостоятельно? Может лучше пользователю вывести инструкцию как что делать или даже ссылку в интернет с более подробным изложением. Сообщение было отредактировано: 8 апр 21, 13:12 |
||||
8 апр 21, 13:19 [22305935] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Вам стоит познакомиться с системами контроля версий. GIT, например. Тогда в процитированном бреде отпадёт нужда. Posted via ActualForum NNTP Server 1.5 |
||
8 апр 21, 13:21 [22305936] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Ну тогда пользователь точно ничего делать не будет - или как минимум, это отсечёт сразу половину пользователей. Так как пользователи ленивые, чтобы в чём-то разбираться. Решение менять программно - предупредив пользователя - наилучшее. Как я вижу - чтобы минимизировать риск потери пользователя - тут решения два - менять программно и перезагружать, не спрашивая пользователя или делать то же самое - но пользователя спрашивать + на случай если пользователь откажется - добавить немного костылей чтобы всё хоть как-то работало пусть и с багами и с крязозябрами в некоторых местах. |
||||
8 апр 21, 13:25 [22305940] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Увы, в этом я тёмный лес :( да и времени нет тут бы с переходом на новую версию Delphi надо разобраться какой ещё GIT ... |
||||
8 апр 21, 13:26 [22305942] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Ну правильно, времени нет потому что вы его тратите на кривые костыли. Ваше право. Posted via ActualForum NNTP Server 1.5 |
8 апр 21, 13:40 [22305949] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1299 |
22305466 Только по-моему нет особого смысла переходить именно на неё, можно и на что-то более позднее. Если хотите что-то относительно старое, то например XE3. Сам долго пользовался 2010, сейчас XE3, пары существенных для меня багов в ней нет по сравнению с 2010. Сообщение было отредактировано: 8 апр 21, 13:56 |
||||
8 апр 21, 13:54 [22305955] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Что за баги в 2010? У 2010 перед XE8 ещё есть преимущество в нетребовательности к ресурсам. Запускается быстро, даже на виртуалках, а XE8 - серьезный проект, который кучу гигов места занимает и который для комфортной работы требует хороший и дорогой ноутбук (который еще довольно непросто выбрать чтобы всё устраивало) с SSD, 8-16 Гб оперативы и прочее. А D7 и на обычном ноуте за 500$ с Intel Core i3, 4 Гб памяти даже без SSD приемлемо работает. А с SSD вообще шикарно. И 2010 по идее должен быть менее требовательным чем XE8/10. |
||||
8 апр 21, 14:17 [22305969] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
08.04.2021 14:17, Анна Петровна пишет: > А D7 и на обычном ноуте за 500$ с Intel Core i3, 4 Гб у меня на старом Celeron-е с 3ГБ памяти на виртуалке (ХР) под Линухом вполне приемлемо крутится. Posted via ActualForum NNTP Server 1.5 |
8 апр 21, 14:21 [22305972] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Вообще мое предложение было такоеunit SomeForm; uses Windows, Forms, SysUtils, ...; uses {$I 'AllVCL.inc'}; uses {$I 'AppUnits.inc'}; в идеале, конечно, сделать .inc файлы самодостаточными, т.е. содержащими "uses" и ";", тогда все упростилось бы до unit SomeForm; uses Windows, Forms, SysUtils, ...; {$I 'AllVCL.inc'} {$I 'AppUnits.inc'} Но после вот этого
уже становится неохота что-то советовать. Ибо как-то озадачивает, что сплайсинг мы могём, а вот отличать механизм подключения модулей в Дельфи от сишных инклюдов - нет. Для справки, подключенное внутри модуля влияет только на этот модуль и недоступно извне. Сообщение было отредактировано: 8 апр 21, 14:37 |
||||
8 апр 21, 14:41 [22305988] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Пример ситуации, когда "в AllVcl.pas надо будет добавить новый модуль", не меняя остальной код всех форм - ?
Все правильно, подобная проктостоматология и должна заставлять авторов неимоверно страдать. |
||||||||
8 апр 21, 14:47 [22305991] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Не знаю, но мне для нормальной работы даже с Delphi 7 нужен ноутбук чтобы было не менее 8 Гб RAM и SSD. Иначе работа превращается в ад. Ведь ещё пара браузеров запущены, разные FAR-менеджеры, Office, PDF-Reader-ы и прочее. C Delphi XE10 вообще всё печально в этом случае - либо нужен хороший ноутбук от 16 Гб RAM, Intel Core i7 (при этом не на каждом ноутбуке есть даже 8 Гб, с а 16 вообще найти проблематично, список решений сильно сужается (а у разных моделей есть свои недостатки например неудобный тачпад, большой вес или что-то еще) и вообще они дорогущие), либо комп (ведь речь идёт не о том, чтобы просто запустить -а о том, чтобы нормально работать). |
||||
8 апр 21, 14:48 [22305994] Ответить | Цитировать Сообщить модератору |
s62 Member Откуда: Жуковский Сообщений: 1299 |
Я сталкивался с таким. Первое, периодически при открытии окна редактора SQL для какого-нибудь Dataset'а возникало AV и бесконечно появляющееся окно - закрываешь его, открывается новое. Так что приходилось закрывать Delphi через диспетчер задач. Было это нерегулярно, то долго нет, то чаще. В XE3 насколько помню, с таким не сталкивался. Второе, это скорее фича, а не баг. Delphi при запуске создает в папке временных фалов один файл шрифта и после какого-то обновления Windows 7 (а может и других версий Windows) система этот файл блокирует от удаления. Если закрыть Delphi и заново запустить в одной сессии Windows, то при запуске - ошибка. Это описанная проблема. Как решение читал предложение какой-то bat-файл создавать, чтобы он запускался по-моему при старте Delphi и обходил это. Я такого не делал, просто вручную переименовывал этот файл, удалить его Windows не давала, а переименовать - да. В принципе перезапускать IDE часто необходимости нет, но когда сочетался первый баг с этим вот моментом, то вот лишний гемор был. В XE3 такого нет. Про меньшую устойчивоcть 2010 тут и другие писали, так что наверное и что-то другое есть. |
||||
8 апр 21, 14:49 [22305995] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Сплайсинг, по-видимому, тоже не особо могём, иначе бы не было столько вопросов :(
Чтобы подключить сразу все нужные модули - и не задумываясь - подключен ли конкретный модуль к данной форме - в любой форме где нужно - например, писать в коде CreateOleObject('Excel.Application') без необходимости вспоминать, что надо ещё прописать в USES ComObj или как он там называется и т. д. |
||||||||
8 апр 21, 14:55 [22306003] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Увы, не совсем очевидно что это "проктостоматология" - по крайней мере, в свое время казалось - что это наоборот - очень удачное решение. Вместо того, чтобы плодить мусор - подключать все необходимые модули сразу одной командой. Разработчики Delphi посчитали по-другому и затруднили так делать в новых версиях но кто ж знал, что так будет ... |
||||
8 апр 21, 14:58 [22306004] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Там дело-то вообще не в этом. GetACP возвращает системную настройку вам. От того, что вы её замените на свою функцию ничего не изменится - потому что кроме вас её никто и не использует. Все системные функции, которым говорят "используй ACP" - просто читают настройку напрямую, им не нужна для этого функция. |
||||
8 апр 21, 15:47 [22306030] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Дело вообще ни разу не в ShowMessage, а в строковых константах как таковых. Исправлять нужно их, а не ShowMessage. |
||||
8 апр 21, 15:49 [22306033] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Да, глючить будет в некоторых местах - но по крайней мере будет хоть как-то работать - да и над уменьшением багов тоже можно работать, создавая различные обёртки с преобразованием Ansi в Utf8 и обратно. А не просто тупо сплошные крякозябры везде. Но ведь при запуске программы пользователя предупреждаем, что нужно сменить языковые настройки - иначе будут проблемы - так что с этим проблем нет - пользователь поработает пару дней в программе, а потом всё же сменит настройку. Но по хорошему конечно да, лучше не мучать пользователя и себя, а переходить на Delphi 2010. Осталось только найти решение с USES ... Сообщение было отредактировано: 8 апр 21, 16:22 |
||||
8 апр 21, 16:23 [22306050] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Исправлять, бегая по всему коду программы совсем не вариант - это еще сложнее будет, чем переход на D2010. Как временные костыли вижу только создавать преобразователи AnsiToUtf8 и обратно для обращений к VCL - и параллельно готовить проект к переходу на D2010. А внутри программы вся логика как и раньше в ANSI Windows-1251. |
||||
8 апр 21, 16:27 [22306052] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Если найти, откуда GetACP берёт значение и поменять его в оперативной памяти - почему-то заканчивается это всё Access Violation и вылетом программы на Windows 10, хотя на Windows 7 прокатывает. По-любому причём Access Violation происходит не в момент перезаписи ячейки, а уже потом, когда какой-то код (тот же ShowMessage) обращается к изменённой ячейке памяти и пытается что-то делать с этим 1251. Не в момент перезаписи Access Violation происходит - потому что если записать в ячейку DWORD:1251, а потом сразу же DWORD:65001 - Access Violation не происходит. Я полагаю, там какой-то код, который ищет данные для кодировки 1251 и просто их не находит, так как их просто нет - по крайней мере, просто изменить в ячейку памяти 65001 на 1251 не прокатывает. |
||||
8 апр 21, 16:36 [22306060] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
А если я не пользуюсь GIT, но пользуюсь WinMerge для сравнения изменений по версиям - это нормально или всё равно не то? Программа сравнивает 2 каталога и изменения в файлах. |
||||
8 апр 21, 17:35 [22306098] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
08.04.2021 17:35, Анна Петровна пишет: > > А если я не пользуюсь GIT, но пользуюсь WinMerge для сравнения изменений по версиям - это нормально или всё равно не то? > Программа сравнивает 2 каталога и изменения в файлах. так вы теряете "хронологию". а при использовании git, или svn - все ходы записаны. и можно легко откатиться к любой ревизии. кроме того, можно параллельно вести несколько веток проекта. переключаться между ними, сливать воедино, снова расщеплять и т.д. Posted via ActualForum NNTP Server 1.5 |
8 апр 21, 17:39 [22306099] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
*рукалицо* Если прогер считает, что список подключаемых модулей - это мусор, и при добавлении некой новой функции ему лениво подключить модуль с ней - ну, тогда я умываю руки. К сообщению приложен файл. Размер - 51Kb |
||||
8 апр 21, 17:41 [22306104] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Это закат солнца вручную. Любая СКВ вам позволит влить багфиксы из ветки старой версии в новую с минимальными трудозатратами. А вы потратите кучу времени на то чтобы сравнить две версии старой ветки и воспроизвести те же действия в коде новой ветки. Но, как говорится в анекдоте, "не жили хорошо, не стоит и начинать". Posted via ActualForum NNTP Server 1.5 |
||
8 апр 21, 17:43 [22306105] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Кажется, нашла решение что делать с USES {$I AllVcl.pas} Вместо Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs там в AllVcl.pas надо написать {$IFDEF Declared Windows} Windows,{$ENDIF} {$IFDEF Declared Messages} Messages,{$ENDIF} {$IFDEF Declared SysUtils} SysUtils,{$ENDIF} ........................... Тогда то, что Delphi будет вставлять всякую требуху в начало USES - дублируя то, что прописано в AllVcl.pas - никак не будет мешать - ошибки Unit redeclared не будет Сообщение было отредактировано: 8 апр 21, 17:48 |
8 апр 21, 17:55 [22306109] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Если программа содержит, скажем, 100 форм - в каждой из которых так или иначе требуется похожий функционал из этих модулей - в чём смысл вручную прописывать в каждой форме в USES кучу одинакового мусора для каждой формы - который кроме того требуется ещё прописывать в определенном порядке иначе будут несовместимости типов с одинаковыми названиями (такое даже в VCL есть!) из разных модулей? Если можно просто написать USES {$I AllVcl.pas}? Кроме того, в проекте присутствуют переписанные модули Forms.pas, Grids.pas, DBGrids.pas и т. д. - которые теперь используют функционал из других моих модулей - поэтому USES должен быть в строго определённом порядке. Понятно желание упростить себе жизнь, объединить подключение всех модулей единой командой для каждой формы. Правда, есть подозрение, что что-то было сделано не так, не по гайдлайнам, не общепринятым способом так скажем, отсюда и проблемы сейчас. |
||||
8 апр 21, 18:03 [22306113] Ответить | Цитировать Сообщить модератору |
delphinotes Member Откуда: Санкт-Петербург Сообщений: 379 |
Анна Петровна, Пихать в uses всё что надо, и что не надо - это, конечно, дурная практика. А вот упорядочивать модули в нужном порядке - это имеет смысл, для этого можно и IDE-визард написать (а возможно оно даже уже где-то есть). |
8 апр 21, 19:48 [22306157] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
Еще раз - выкиньте свой инклуд и пропишите в каждом модуле требуемый именно этому модулю uses и все. И забудьте о проблеме навсегда |
||||
8 апр 21, 21:41 [22306179] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Да бесполезно убеждать. Что совой об пень, что пнём об сову. Особенно после этого
"Всё прогнило, нужно всю систему менять" Сообщение было отредактировано: 9 апр 21, 11:31 |
||||||||
9 апр 21, 11:37 [22306356] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Интересно, а если просто перехватить все функции вывода текста типа DrawTextA и TextOutA и перекодировать в W на лету, то получится поправить хотя бы весь вывод? |
9 апр 21, 12:41 [22306403] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
avp_, нет. Потому что на вход будут идти смешанные строки: какие-то в UTF-8, какие-то в ANSI. |
9 апр 21, 16:07 [22306571] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Как я понимаю, вывод текста ещё зависит от используемого шрифта. В общем, надо определиться и желательно использовать во всей программе один шрифт. Потому что с MS Sans Serif одни особенности (и алгоритмы перехвата), с Arial другие, чтобы тексты отображались нормально и т. д. В моем случае во всей программе Arial, RUSSIAN_CHARSET, SetThreadLocale(1049) - но в некоторых местах может оказаться и MS Sans Serif или что-то другое. В общем, как я понимаю, по-нормальному вопрос в рамках Delphi 7 не решается - речь может только вестись о минимизации глюков (и в том, чтобы убедить пользователя отключить злополучную галочку). |
||||
9 апр 21, 16:39 [22306586] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Почему нет - очень даже рассматриваю такой вариант. Причем даже до размещения вопроса на этом форуме. Просто очень не хочется так делать - очень уж удобно и красиво модули сгруппированы в Delphi 7 и никаких проблем. В Delphi 2010, кстати, исходники VCL в комплекте есть если сборка нормальная - тот кто говорил про мою кривую сборку - был прав. |
||||
9 апр 21, 16:44 [22306590] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Разве что если только вне зависимости от исходного формата строки - пытаться распознать строку, в каком она формате и всё равно пытаться выполнять преобразование. А в случае неудачи преобразования - оставлять тот формат, что был. Например, преобразовываем UTF-8 в ANSI а если в процессе преобразования произошла неудача - оставляет результат в ANSI т. к. скорее всего строка и так в ANSI. Конечно, понимаю, что поведение программы в этом случае будет непредсказуемым и некрасивым и вообще за такое надо руки отрывать, разве что использовать такое как вариант - если нужно чтобы отображалось без крякозябр любой ценой, даже ценой потери стабильности программы ... |
||||
9 апр 21, 16:50 [22306602] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Как я понимаю, гораздо надёжнее и стабильнее - перехватывать свойства Text, Caption и прочие у объектов и писать свои наследники стандартных объектов. По мере обнаружения крякозябр в разных местах программы - добавляем перехватчики для разных компонентов и свойств. Например, аналогично Text перехватываем обращения к Hint, аналогично Button перехватывает обращения к Edit и т. д. И разумеется, у всех компонентов указать одинаковый шрифт (например, Arial) и RUSSIAN_CHARSET. Чтобы поведение перехватчиков было не случайным, а предсказуемым. Как мне кажется, это единственный способ обеспечить более-менее стабильную работу программы без перехода на юникодный Delphi (написать такой модуль, который подключать ко всем формам программы в секции INTERFACE после USES всех стандартных VCL-модулей и до USES своих модулей (чтобы они - если работают с VCL - использовали уже новые обёртки)): UNIT UtfVcl; ....... type TUtfButton=class(TButton) public procedure SetCaption(s: string); function GetCaption: string; property Caption: string read GetCaption write SetCaption; end; TButton=class(TUtfButton) end; .......... IMPLEMENTATION var mode: integer=0; procedure TUtfButton.SetCaption(s: string); begin if mode=0 then inherited Caption := s else inherited Caption := AnsiToUtf8(s); end; function TUtfButton.GetCaption: string; begin if mode=0 then result := inherited Caption else result := Utf8ToAnsi(inherited Caption); end; .............. BEGIN if GetACP=65001 then mode:=1; SetThreadLocale(1049); END. Сообщение было отредактировано: 9 апр 21, 16:55 |
||||
9 апр 21, 17:01 [22306611] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
вам непременно нужен ещё один велосипед? |
||||
9 апр 21, 17:07 [22306613] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Откуда? UTF-8 будет мне видится только оттуда где что то вводилось с клавиатуры. |
||||
9 апр 21, 17:57 [22306648] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
avp_, из 22305574, 22305637 и 22305592 |
9 апр 21, 19:28 [22306706] Ответить | Цитировать Сообщить модератору |
JayDi Member Откуда: Сызрань, Россия Сообщений: 4173 |
Пара мыслей, может кому пригодится: 1. Давно перешел на хранение настроек в json-файле (если есть такая возможность). Очень удобно. Причем не надо придумывать ничего чтением, записью, преобразованием данных. Очень удобно и наглядно в коде использовать. Компонент JsonDataObjects 2. Был опыт поддержки с кучей форм в двух версиях делфи (2006 и 2009, если правильно помню) -- ничего хорошего не приносило, иногда что-то левое пробиралось в dfm и приходилось вручную чистить-восстанавливать. Вздохнул с облегчением, когда все перешли на обновленную версию. |
9 апр 21, 20:25 [22306747] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Не нужно. Нужно только чтобы тот код, который уже есть - продолжал нормально работать и ни в коем случае не стал хоть на 1% менее стабильным. Хорошо, что пока у большинства пользователей эта опция отключена и вообще многие вообще на Windows 7. С TntComponents если на него переходить стабильность программы может пострадать и у основной категории пользователей да и зачем на них переходить уж лучше сразу тогда наи новую версию Delphi, да и вообще любой компонент в том числе TntComponents это тоже дополнительный костыль, который также затруднит переход на новые версии Delphi в дальнейшнем. Логика тут в том, что у основной массы пользователей всё должно остаться как есть и чтобы не стало хуже. А у тех, у кого опция эта включена - хотя бы основной функционал чтобы работал и если и будут где-то какие-то глюки - то пусть уж лучше они будут только у тех, у кого данная опция включена (а если они будут обращаться в техподдержку - предлагать эту опцию отключить), но не у вообще всех. |
||||||||
9 апр 21, 23:12 [22306810] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Кажется, еще один сторонний компонент - то есть костыль. Который затруднит переход на новые версии Delphi и дополнительно привяжет к Delphi 7. Как мне кажется, при переходе на новые версии Delphi сам по себе появляется доступ ко многим новым стандартным компонентам - которых нет в Delphi 7 и в новых версиях Delphi придётся изобретать меньше велосипедов, тк в комплекте больше возможностей "из коробки". |
||||
9 апр 21, 23:16 [22306814] Ответить | Цитировать Сообщить модератору |
JayDi Member Откуда: Сызрань, Россия Сообщений: 4173 |
В делфи 7 вообще ничего нет для работы с JSON (собственно, даже JsonDataObjects работает только с 2009 -- но она как пример дана). Я к тому, что у делфи идет настолько кривая и раздутая JSON-библиотека, что тупо отпугнет любого разработчика, кто захочет с ней работать "ради облегчения" процесса -- в результате они так и сидят на устаревших ini-файлах. |
||||||||
9 апр 21, 23:21 [22306816] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Использую для распознавания JSON велосипед под названием OLE-объекта MSScriptControl.ScriptControl. Как вариант, можно еще использовать Node.js как внешнюю программу для разбора JSON - вызывая скрипт на Node и возвращая ответ в виде файла. В общем, и так понятно - надо уходить с Delphi 7 - иначе с каждым годом количество вынужденных велосипедов будет расти и проблема велосипедов ещё в том, что зачастую менее эффективны, чем стандартные решения - в итоге дойдет до того, что программа для своей работы будет требовать Intel Core i7, да ещё и работать при этом неспешно. |
||||
9 апр 21, 23:55 [22306832] Ответить | Цитировать Сообщить модератору |
Cobalt747 Member Откуда: Сообщений: 2300 |
Анна Петровна, вот же вы выдумщица ))) для JSON в D7 есть прекрасный superobject. |
10 апр 21, 00:10 [22306838] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Еще один сторонний велосипед с GitHub. Неизвестно, кто его делал и неизвестно, как он работает и какие там глюки. Скорее всего, он гораздо эффективнее, чем предлагаемое мной решение. Но вот опасаюсь - если на него, например, завязать много логики в программе, а потом он заглючит - копаться в чужом коде и выяснять причины ошибок это ад для меня по крайней мере. Со своими бы велосипедами разобраться они хоть и с квадратными колёсами, зато обкатаны и работают предсказуемо. А стандартным компонентам и программам вроде Node.js я по умолчанию больше доверяю, чем разным сторонним решениям. Но если конечно - нужна именно скорость и стандартных решений нет, а велосипеды с квадратными колёсами едут слишком медленно - и единственный нормальный вариант использовать стороннее решение - приходится сжав зубы качать и использовать на свой страх и риск. |
||||
10 апр 21, 00:31 [22306843] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Кстати, с переходом на Delphi 2010 гадость обнаружилась. Не даёт собака писать длинные процедуры. Выдаёт ошибку E2283 Too many local constants. Use shorter procedures приходится разбивать длинную процедуру на несколько более коротких Конечно я всё понимаю, писать несколько тысяч литералов в одной процедуре это не есть хорошо. Но с другой стороны зачем выдавать ошибку достаточно предупредить, что так делать нехорошо. Чем-то напоминает глупое ограничение еще из Турбо Паскаль - размер кода не должен превышать 64 килобайта. Смешно - но изучая Турбо Паскаль в свой время - столкнулась с этим ограничением (не более 64 Кб кода) буквально на 7-й день изучения. Используя многократно Copy&Paste это совсем даже не удивительно. |
10 апр 21, 00:37 [22306846] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
А ведь говорили Вам, что 2010 - глючная. Но некоторые просто обязаны наступить на грабли лично... Posted via ActualForum NNTP Server 1.5 |
10 апр 21, 00:45 [22306848] Ответить | Цитировать Сообщить модератору |
JayDi Member Откуда: Сызрань, Россия Сообщений: 4173 |
Они годами отлажены. Обычно, если библиотека "глючит" -- значит в нашем коде было сделано что-то не то. Шанс на ошибку в самой библиотеке минимален. В критическом случае можно либо самостоятельно поправить исходники, либо поискать альтернативы. В свое время так пришлось переехать с SimpleXML на OXml, т.к. первый не поддерживал некоторые специфические конструкции, кодировки и большие объемы. Но сторонняя библиотека НАМНОГО лучшее решение, нежели городить огород со сторонними скриптами (msscript) или сервисами (node.js). Сообщение было отредактировано: 10 апр 21, 01:03 |
||||
10 апр 21, 01:09 [22306854] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
|
||||
10 апр 21, 01:53 [22306865] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
На 4K экран в портретной ориентации ![]() |
||||
10 апр 21, 09:59 [22306895] Ответить | Цитировать Сообщить модератору |
LocksmithPC Member Откуда: Сообщений: 268 |
А можно взглянуть на такую процедуру?
А вот за посмотреть на такое я бы даже денег заплатил. 7-й день, 64 тысячи символов... |
||||||||
10 апр 21, 12:05 [22306931] Ответить | Цитировать Сообщить модератору |
crossa Member Откуда: Сообщений: 90 |
Если "ну, вот прям позарез" надо хранить текстовые строки внутри программы, то оформите это как ресурс. Создайте RES-файл: MyData RCDATA my_data.txt добавьте его в программу:
{$R MyData.res}
загружайте по мере надобности с помощью FindResource и LoadResource. Но лучше хранить текстовые данные во внешних XML-файлах. Быстро загружаются, имеют гибкую структуру, универсальный формат. И в Delphi 2010 есть все необходимые инструменты для работы с XML. |
||||
10 апр 21, 14:21 [22306957] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Этого кода, увы, уже нет. На 7-й день изучения программирования, разумеется, мне были неизвестны такие вещи как работа с файлами. И даже работа с массивами. Но зато очень хорошо было известно, что такое Copy&Paste. Скопировать, вставить, а потом что-то поменять в скопированном коде. Время было начало 2000-х, никто нигде ничего не мог подсказать - и Интернета нормального небыло. Спрашиваю у учительницы по информатике в школе - что делать не дает злой Турбо Паскаль писать код более 64 Кб (а у меня на компьютере целых 128 мегабайт оперативы, как так-то, что за дурацкие ограничения) - она офигела какие 64 килобайта о чем вы никогда с таким не сталкивалась, а тут уже на 7-й день ... и ничего не может предложить. Отец у своего знакомого программиста тогда спросил, что делать - он ответил, пусть разбирается с модулями. Разобралась через 2-3 месяца только, модули оказалась для меня жутко сложная штука тогда. А через год, в 11-м классе (когда уже код тоже был некрасивым, но не таким диким, как в первые дни) - ради интереса попробовала сократить этот код, что был написан - получилось в 10 раз короче исходного и делает то же самое, причем меньше глючит при этом. В 11-м классе прикол был. Учительница информатики объясняет функция random от 10 возвращает значения от 1 до 10. Я не удерживаюсь и говорю - нет, от 0 до 9 (это мне уже после месяца начала изучения Турбо Паскаля было известно). Спорили около 5-10 минут, я продолжаю отстаивать свою позицию и не сдаюсь. Ну что делать - подошли к компу, написали программу, действительно выдает от 0 до 9. Учительница, собака, затаила злобу и поставила годовую оценку по информатике 4, а не 5. Реву было тогда много от такой несправедливости но что сделаешь учительница может знать меньше, но ведь она тебе оценки ставит, а не ты ей ... |
||||
10 апр 21, 15:57 [22306996] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Да это уже решилось проще - разбитием длинной процедуры на 5 более коротких. Просто неожиданно оказалось когда более старый D7 позволяет а в новом D2010 так нельзя. Рефакторинг кода - конечно, штука хорошая но в этой процедуре он особо не нужен пока. |
||||||||
10 апр 21, 17:03 [22307009] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Вы не поверите, но при переходе в юникод строки увеличились в размерах вдвое. А лимит остался прежним в байтах. Сообщение было отредактировано: 10 апр 21, 18:05 |
||
10 апр 21, 18:11 [22307032] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Константы же можно вынести за подпрограмму. Но разбивать на мелкие куски это более правильно. Парсить json через вызов ноды... черт, я уже читаю этот топик как захватывающий триллер ))) |
12 апр 21, 10:35 [22307488] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Получается велосипед с квадратными колёсами. Но если часто парсить не надо вполне себе решение. Понятно, что при большой нагрузке такой велосипед поедет медленно. Правда, у Node.JS есть неоспоримое преимущество перед любыми сторонними компонентами Delphi - уж раз он настолько популярен - на 99,999% при таком подходе не будет проблем с багами - по крайней мере в таком простом сценарии . |
||||
12 апр 21, 11:15 [22307517] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
хххл, перестань, что ты делаешь... ![]() |
12 апр 21, 11:34 [22307531] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
12.04.2021 11:15, Анна Петровна пишет: > у Node.JS есть неоспоримое преимущество перед любыми сторонними компонентами Delphi - > уж раз он настолько популярен - на 99,999% при таком подходе не будет проблем с багами - > по крайней мере в таком простом сценарии. уж если дитяти суждено упасть, то и сидя на полу упадёт с кровати. © Posted via ActualForum NNTP Server 1.5 |
12 апр 21, 11:41 [22307533] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Новый хит от автора "Подключаемые модули есть мусор" :) |
||||
12 апр 21, 11:54 [22307543] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
По сути так оно и есть - лишние конструкции, издержки языка и структуры VCL. Кто работал в 1С - поймёт, никакого подключаемого мусора. Даже в Java можно написать что-то подобное import java.util.*; import java.io.*; а не импортировать каждый модель отдельно - когда например мне как программисту не особенно интересно, как оно там технически устроено внутри VCL - главное чтобы работало. Ну а работая в Delphi - видимо, надо смириться - когда в начале каждой формы ворох автоматически подключаемых модулей, причем в каком попало порядке (в каком порядке Delphi захочет, так и накидает). Ну либо не использовать визуальный редактор и VCL, но тогда непонятно, зачем Delphi. Сообщение было отредактировано: 12 апр 21, 23:32 |
||||||||
12 апр 21, 23:38 [22307892] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2792 |
В новых IDE есть {$REGION} специально для эстетов. |
13 апр 21, 00:09 [22307902] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
import java.io.*; отличается от добавления в uses IOUtils Тем что юзается алиас? Но программисту также надо держать в голове когда и что подключать. И так практически во всех языках. Правда в делфи отстойный механизм подключения юнитов, по сравнению с тем же C# в VS, когда среда сама предлагает подключить нужную сборку |
||||
13 апр 21, 01:41 [22307913] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Я конечно понимаю, что среда сама делает и понимаю, что бесплатно. Но очень уж хотелось бы это как-то отключить. Я ещё понимаю - в случае если пользоваться визуальным редактором форм Delphi - чтобы среда добавляла что-то в класс формы, методы в секции implementation ну и до кучи модули в секцию USES. Но я совершенно не понимаю - зачем среда добавляет ненужные модули в секцию USES если я просто открываю, скажем, модуль Unit2.pas - делаю там правки и сохраняю (файл-->сохранить как) - так вот, в момент сохранения среда что-то пропихивает своё в секцию USES. Хотя казалось бы, команда называется "Сохранить" - ну так и сохраняй - зачем при сохранении что то в модуле менять? Притом что если, скажем, файл Unit2.pas не открывать в Delphi - он этим самым Delphi прекрасно компилируется. |
||||
13 апр 21, 10:33 [22308039] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Спасибо, посмотрю какие ещё есть директивы компилятора. Может есть какая нибудь директива, которая вообще отключает генератор кода для конкретного модуля, сохраняя при этом возможность редактировать вручную. Хотя надежды мало, конечно ... |
||||
13 апр 21, 10:38 [22308042] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Ладно, о чём спорить - понятно, что всё использование Node.JS для парсинга JSON не от большого ума и вообще это всё лирика. А собственно по переходу на D2010 (или вообще на любую юникодную Delphi) - как вы думаете - хорошая ли это идея - заменить во всех файлах проекта примерно так: StringReplace('string ', 'AnsiString ', s) StringReplace('char', 'AnsiChar', s) StringReplace('chr(', 'AnsiChar(', s) StringReplace(': array of string', ': array of AnsiString', s) StringReplace('of string', 'of AnsiString', s) StringReplace('of char', 'of AnsiChar', s) и т. д.? Тогда в стандартных библиотеках VCL всё останется как было - тип string будет уже как WideString в новой Delphi. А в моём коде string будет заменено на AnsiString. Делал ли кто что-то подобное - это нормально при переходе на новые версии Delphi - или это очередной велосипед? |
13 апр 21, 10:38 [22308044] Ответить | Цитировать Сообщить модератору |
white_nigger Member Откуда: Тула Сообщений: 2520 |
Что?! Вся идея заключается в уходе от AnsiString чтоб не иметь гемора с языками. А тут предлагаете вернуть его "эмуляцией Delphi 7" в юникодной среде? Забейте уже на AnsiString. А если уж так трясутся поджилки, то для начала переведите СВОЙ код на WideString, добейтесь нормальной работы. И потом переход на юникодную делфу будет тривиальным.
Сообщение было отредактировано: 13 апр 21, 10:51 |
13 апр 21, 10:58 [22308056] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Среда добавляет модули, без которых компоненты на форме не будут работать.
Не верю. Пример в студию. |
||||||
13 апр 21, 14:10 [22308222] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
|
||||
13 апр 21, 15:04 [22308274] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Как ни странно, если создать чистый проект и подключить мои USES {$I AllVcl.pas}; В единственную форму - Delphi ничего не корежит, не подставляет в секцию USES и нормально компилирует. Если же в моём проекте - несмотря на то, что в {$I AllVcl.pas} есть все нужные модули - Delphi всё равно их пехает в USES перед моим {$I AllVcl.pas}, а потом ругается, что Duplicate unit и не компилирует. Впрочем, решается всё если в AllVcl.pas прописать {$IF not Declared(SysUtils}}SysUtils,{$IFEND} ...... В общем, буду разбираться, почему так происходит. Хотелось бы конечно найти какую нибудь директиву - чтобы иметь возможность среде Delphi вообще запретить менять текст модуля при сохранении - особенно если не собираюсь больше для этой формы использовать визуальные средства Delphi. |
||||
13 апр 21, 16:53 [22308367] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
У меня там есть переопределение класса TForm - создание наследника TForm и использование наследника TForm вместо оригинального во всех формах (чтобы иметь возможность вносить изменения централизованно, сразу во все формы - например, в заголовок добавлять дополнительный текст или не допускать вызова OnActivate более 1 раза, коррекция некоторых косяков некоторых VCL компонентов например DateTimePicker и т д). Возможно, в этом всё и дело ... |
||||||||
13 апр 21, 16:58 [22308371] Ответить | Цитировать Сообщить модератору |
Dimitry Sibiryakov Member Откуда: Сообщений: 52921 |
Вообще-то визуальное наследование форм появилось ещё в Delphi 2, но вам же учиться некогда, костыли строгать надо... Posted via ActualForum NNTP Server 1.5 |
13 апр 21, 17:11 [22308381] Ответить | Цитировать Сообщить модератору |
Fr0sT-Brutal Member Откуда: Сообщений: 682 |
Тут так же, как и с файлом проекта dpr - среда считает его своей территорией и перекраивает как ей вздумается. В теории можно сделать визард, чтобы убирал эти автодополнения, но легче смириться. Или же настроить before build скрипты, чтобы удаляли ненужное |
||||
13 апр 21, 17:58 [22308401] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Думаю, скрипт на AutoIt или Python сделать, который будет анализировать модули и выпиливать этот мусор - совсем не проблема. Но пока не буду - проблема эта хоть и криво, но решилась другим способом с помощью {$IF not Declared(...)}...{$IFEND} и без выпиливания нормально всё работает. А вот с before build скриптами идея интересная, надо разобраться ... |
||||
13 апр 21, 22:24 [22308489] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Да, во время шторма навигации как-то учиться не очень, приходится заниматься тем, что умеешь - пилить костыли. А когда шторм проходит - желание учиться тоже проходит и так ведь всё нормально можно потихоньку кодить и не думать о плохом. Так вот неправильно живём и я полагаю многие так живут :( Сообщение было отредактировано: 13 апр 21, 22:19 |
||||
13 апр 21, 22:27 [22308495] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Вы будете удивлены, но после автоматической замены string --> AnsiString, char --> AnsiChar и т. д. и еще парой десяткой правок вручную проект успешно скомпилировался и запустился (хоть и с кучей багов и сообщений) на Delphi XE8. На Delphi 2010 только скомпилировался, но не запустился сплошные Access Violation. Вот и думайте, какая версия Delphi стабильнее. Походу, проще купить мощнее комп и сразу переходить сразу на XE8, чем мучаться с глючной 2010, а потом в итоге всё равно переходить на XE8. Думаю только - почему XE8 папка C:\Program Files (x86)\Embarcadero занимает 21 Гб что туда такого напехали. Можно ли оттуда что нибудь удалить и вообще заставить XE8 работать побыстрее ... |
13 апр 21, 23:42 [22308519] Ответить | Цитировать Сообщить модератору |
makhaon Member Откуда: A galaxy far far away Сообщений: 3831 |
не удивлен ни разу. сам переносил толстые проекты, переносится чаще всего десятокой правок. ну если код, конечно, не убитый костылями. |
||||
14 апр 21, 00:35 [22308534] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Правок около 100. Проект убитый костылями. Перенесся с отключением кучи функций (надо теперь постепенно восстанавливать и включать) и с кучей багов, также с эмуляцией Delphi 7 в среде XE8 (во всех функциях AnsiString и AnsiChar) - но в целом работает. Удивительно то, что на XE8 оказалось проще перенести, чем на 2010. Теперь буду думать перейти все таки на XE8 или навставлять костылей и остаться пока на D7. Вариант с D2010 точно теперь отметается, либо сразу XE8, либо оставаться на D7 и дальше городить костыли. |
||||
14 апр 21, 01:06 [22308544] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
|
||||
14 апр 21, 13:17 [22308764] Ответить | Цитировать Сообщить модератору |
avp_ Member Откуда: Сообщений: 100 |
Всё хотел спросить на что влияет параметр Charset у шрифта. В каких случаях с DEFAULT_CHARSET получается криво, а с RUSSIAN_CHARSET нормально? |
14 апр 21, 13:36 [22308776] Ответить | Цитировать Сообщить модератору |
Мимопроходящий Member Откуда: бурятский тундрюк, эсквайр Сообщений: 32207 |
14.04.2021 13:36, avp_ пишет: > Всё хотел спросить на что влияет параметр Charset у шрифта. В каких случаях с DEFAULT_CHARSET получается криво, а с RUSSIAN_CHARSET нормально? он задаёт "шифтинг" юникодных шрифтов для неюникодных приложений. сильно упрощенно можно сказать, что у юникодного шрифта есть множество "кодовых страниц". параметр Charset позволяет выбрать нужную "страницу". обычно дефолтный "шифтинг" выставляется в реестре в разделе HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontSubstitutes. обрати внимание на циферки после названия шрифта. для "нерусской" винды это самый "шифтинг" будет совсем не тот, который необходим для win1251. поэтому, при выставленном DEFAULT_CHARSET на такой винде будут крякозябры при отображении win1251. Posted via ActualForum NNTP Server 1.5 |
14 апр 21, 13:47 [22308786] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Разумеется, сразу и не решится. Более того, сначала багов будет еще больше. Но борьба с багами - в любом случае это неизбежный процесс при переходе на новую версию Delphi - особенно юникодную. Но если string --> AnsiString, char --> AnsiChar не сделать то проект вообще не работает, даже с багами, так как очень много там заточено на 1-байтную кодировку - получается что лучше сделать string --> AnsiString, char --> AnsiChar при первоначальном переходе на новые Delphi, а потом уже в новой Delphi потихоньку исправлять баги и избавляться где надо от AnsiString итд. |
||||||||
14 апр 21, 14:27 [22308824] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Еще есть идея - создать свой тип, назвать type string7 = AnsiString char7 = AnsiChar и переходить не на AnsiString, а на тип string7 - который первоначально будет = AnsiString а потом пробовать иногда его менять на string и следить за багами |
14 апр 21, 14:33 [22308835] Ответить | Цитировать Сообщить модератору |
GunSmoker Member Откуда: Сообщений: 3210 |
Из личного опыта скажу что пересобрать в Unicode ничего не меняя - проще, чем менять весь код на Ansi, а потом обратно. |
14 апр 21, 18:20 [22308987] Ответить | Цитировать Сообщить модератору |
makhaon Member Откуда: A galaxy far far away Сообщений: 3831 |
Анна Петровна, в целом разумно, пробуй |
14 апр 21, 19:31 [22309019] Ответить | Цитировать Сообщить модератору |
makhaon Member Откуда: A galaxy far far away Сообщений: 3831 |
с нормальным кодом так и есть. но судя по описанию код там далек от идеала :) сделано абы работало. вот абы и работает |
||||
14 апр 21, 19:33 [22309021] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Судя по всему, по экспериментам компиляции в разных вариантах - оказалось, в моём случае лучше всего что-то среднее. Не менять прям всё на Ansi, а поменять на ANSI только код модулей, которые самописные и не являются модулями форм. Потому что если поменять на UTF-8 - мой код в 95% случаев перестанет работать или будет много багов, там много кода для работы с файлами и т. д. - где важно чтобы именно 1 символ строки соответствовало 1 байту и разделить код, который можно перевести на UTF-8 и который нельзя - довольно сложно - проще всё оставить на ANSI. Код модулей форм, код, сгенерированный Delphi и всё, что связано с VCL стараться не трогать - пусть будет в Unicode. В общем, в процессе работы проекта будет много перекодирований из Ansi в Unicode и обратно (при обращении из форм к моим самописным модулям) - но как я понимаю, это не проблема - в конце концов работать будет уж точно не хуже, чем сейчас на Delphi 7, а над багами можно работать. По алгоритмам перекодирования из Ansi в Unicode и наоборот не проблема - у меня только русский и английский - можно смело хранить в Ansi в нужной мне кодировке (Windows 1251) - а не в той однобайтной, что Windows подсунет. На крайний случай можно вообще написать свои процедуры перекодирования Ansi-->Utf8 и обратно чтобы не зависели вообще никак от системных настроек. В общем, написать нормальный скрипт замены - который максимально - насколько это возможно - произведёт замены только там, где это нужно - чтобы можно было потом обойтись минимальным количеством правок. Кстати, уже сейчас - когда часть кода осталась на Unicode, а мой на Ansi, глюков стало гораздо меньше. |
||||
17 апр 21, 01:46 [22310089] Ответить | Цитировать Сообщить модератору |
Анна Петровна Member Откуда: Сообщений: 68 |
Кстати, спасибо за советы. С Delphi 7 тоже получилось. В 99% кода при включенной опции . Далее пишу что было сделано - на случай если кому ещё может пригодится. "Бета-версия: Использовать Юникод (UTC-8) для поддержки языка во всем мире"/"Use Unicode UTF-8 for worldwide language support" больше нет крякозябр. За счет добавления дополнительных костылей (получилось перехватом обращений к свойствам Text, Caption компонентов - перехватчики пришлось писать для каждого компонента свои - тк одни хранят данные в Ansi, другие в Unicode - но в целом ничего страшного и не такие уж костыли - всё вполне компонуется в один модуль - но если посчитать общее количество костылей за все годы по теме нормального отображения ANSI - можно испугаться). Хотя если подумать - сколько усилий за последние годы было потрачено на борьбу с ветряными мельницами в виде крякозябр на разных системах (не конкретно то, что обсуждалось именно в этой теме, а вообще всё) - там целый лес из костылей - возможно, проще было сразу на юникодную версию Delphi перейти ... Сообщение было отредактировано: 17 апр 21, 01:47 |
17 апр 21, 01:54 [22310091] Ответить | Цитировать Сообщить модератору |
yemets63 Member Откуда: Самара Сообщений: 1441 |
хотел помочь, но не понял вопроса. точнее потратил время, все прочитал, советов много, но причина проблемы мне не понятна. и так к чему я это всё, засомневался, а не выстрелит ли у меня такое, нет русских символов, а уменя тут Умляуты и Китайцы по мимо русского. для проекта использую 2 Delphi Seattle и Berlin, и 3-й есть установленный CG2010 после успеха на 2-х двельфи, немного попробовал на CG2010, тоже успех. сейчас в проекте использую две базы Oracle 10G и MariaDB. заказчику надо 2 базы. пофиг, делаю. и так CHARSET в базах равен UTF8 протестировал свой софт на виртуальных машинах windowsXP, 2008R2, windows7, windows10 в итоге надпись, как в интерфейсе дельфи, так и в базе, сохранение и получение из базы в базу, даже в одном поле, полет нормальный Language / Sprache / Язык / 语言 / 言語 / and Ümläut но содержимое не отразилось здесь, прикрепил картинку если Вы, Анна Петровна переводите двоичный файл и увас там терется инфа, а не русские буквы, то поиграйте между Ansistring и Widechar, я уверен быстро найдете решение. и вместо ReplaceStr ипользуйте StringReplace больше не чего сказать |
17 апр 21, 21:16 [22310356] Ответить | Цитировать Сообщить модератору |
yemets63 Member Откуда: Самара Сообщений: 1441 |
yemets63, ах не, все отразилось, в предварительном не видно было |
17 апр 21, 21:17 [22310358] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: 1 2 3 4 5 6 7 [все] |
Все форумы / Delphi | ![]() |