вызвано всего лишь указателями (не особенность именно Паскаля)? Просто интересно.
Возьмем любые другие указатели — на динамически создаваемые структуры, например. Указатели на функции, в конце концов. Приведение всех этих указателей — тут и без классов полно «небезопасного» и слабо-типизированного.
Реализация в каком языке вам кажется наиболее удачной?
Лучший, на мой взгляд, из «старых» Бейсиков — QuickBasic 4.5 от MS со всеми процедурными и пр. «наворотами» разрабатывался с 85 по 90 год, если не ошибаюсь. До нас, видимо, доходило не сразу.
Хочешь научить человека программировать неправильно — научи его Бейсику
Интересно — сколько раз слышал эту фразу — никто так и не смог пояснить ее. Обычно все заканчивается очень многозначительным видом и подёргиванием плечами. Может быть, вам удастся?
Обычная процедурная парадигма, всё те же базовые управляющие конструкции. А вот поди ж ты!
Первая моя программа была написана на Фортране, на бумаге. Но на Бейсике писал очень много. Особенно на QuickBasic 4.5, у которого был нормальный компилятор и линкер. Чего только не было — игры, например, клон AlleyCat ( оригинал не запускался на моем Pentium 2 класса процессоре, решил написать свой клон). Программы пересылки файлов, обмена электронными сообщениями в сети, образованной «кольцом» через ком-порты. Простейший шутер от первого лица с лабиринтами, аптечками и 1 видом врагов. Учет домашних расходов. Библиотеки псевдо-графических окон и элементов управления, потом — оконный менеджер для своих программ (640*480*16 перекрывающиеся окна, перемещение, изменение размеров, кнопки, эдитбоксы, чекбоксы и радиобаттоны). Всего и не упомнить.
Извините, пожалуйста, за возможно глупый вопрос.
Разве в стандартах тех лет определяется значение константы TRUE? У меня почему-то в голове отложилась концепция «0=FALSE, остальное — TRUE». Если построить транслятор, который будет выдавать результатом 1 > 0, скажем, 10 — разве это будет отклонением от стандарта?
Тут надо отметить следующее: 1)в моем случае каждое приложение регистрировало по одному RWM атому, не пачкой; 2)Приложения запускались в non-interractive session, из-под сервиса, т.е. от SYSTEM.
Может быть, в этом разница.
А у меня все запускается. Там возвращается 0, ну и дальше все типтоп.
Эм, я не совсем правильно выразился. Да, 0, но просто в последствии там еще потребуются атомы при инциализации графики, и initialization какого-то из модулей просто вылетает с out of resources. Не помню последовательность, но после controls еще что-то графическое будет инициализироваться точно.
ObjectFromhWnd выглядит как костыль — получение дельфийского объекта из виндового хэндла. Видимо, использовался в древности для связи WinAPI — gui кода и VCL.
Промахнулся с ответом, извините — внизу простыня -вторая часть ответа.
Да, именно. Используется только в одном месте, поэтому можно использовать тупо константу.
Кстати в MSDN не сказано что винда не чистит атомы от RegisterWindowMessage
В MSDN сказано, как я цитировал в посте:
The message remains registered until the session ends.
Я проверил на WIN7 со всеми обновлениями. Сожрал атомы и прибил процесс. Через некоторое время винда очистила хендлы, но очистила их далеко не сразу после регистрации
Атомы вообще или именно RWMовские?
На WS2008 нет очистки, мы именно на 2008м увидели это впервые. И атомы накапливались там не один день.
Какого-то лешего разработчики Windows решили, что в принципе достаточно использовать один скоуп для RegisterClipboardFormat и RegisterWindowMessage
Это тянется, наверняка, чуть не с 1.0. В третьей версии атомы такие же, насколько я помню из обсуждения этой проблемы. Так что тогда они экономили ресурсы
Да и потом, неудача с RM_GetObjectInstance VCL не огорчит
Ну, как вам сказать — сообщение-то это VCL не нужно, но вот приложение не запустится. Вообще.
Ситуацию спасает лишь то, что винда периодически (и неизвестно при каких обстоятельствах) чистит эти атомы.
Я, к сожалению, не могу этого подтвердить. MSDN утверждает, что RWM атомы живут до конца сессии, и именно это я наблюдаю.
Это действительно тривиальный код — имея под руками SDK .h заголовки, процедура перехвата пишется за пол-часа.
Готовое решение можно посмотреть здесь: проект uall.
Или просто гуглить по «delphi iat hook», первые 3 результата — вполне.
Свой код привести не могу, часть коммерческого продукта, извините.
Сам код перехватчика в простейшем варианте примерно таков:
function myRegisterWindowMessageA(name: PAnsiChar): UINT; stdcall;
...
...
len := lstrlen(name);
if copy(name, 1, 10) = 'ControlOfs' then
Result := OriginalRegisterWindowMessageA(PChar('abcd'));
else
Result := OriginalRegisterWindowMessageA(Name);
Но его можно допилить для повышения эффективности.
В принципе, это здравая идея, но во-первых, перекомпилировать самому RTL не всегда безопасно, могут быть какие-то отличия в директивах и пр. Положиться на борландовскую RTL можно, ее все используют, и большинство ошибок отловлено. Во-вторых, могут возникнуть проблемы вида «unit was compiled with different...», т.е. объем перекомпиляции может быть большим. Ради исправления одной инструкции это нецелесообразно.
Так да — строку RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
Надо заменить на RM_GetObjectInstance := RegisterWindowMessage(PChar('ControlAtomString'));
Если кто-то соберется перекомпилировать библиотеки, могут понадобиться ключи для system.pas и подобных:
Простите, а чем дополнительный код плох? В каком еще АЛУ есть вычитатель вообще?
вызвано всего лишь указателями (не особенность именно Паскаля)? Просто интересно.
Возьмем любые другие указатели — на динамически создаваемые структуры, например. Указатели на функции, в конце концов. Приведение всех этих указателей — тут и без классов полно «небезопасного» и слабо-типизированного.
Реализация в каком языке вам кажется наиболее удачной?
Да, отсутствие четкого стандарта (стандарты есть, но вариантов — море) играет злую шутку.
Интересно — сколько раз слышал эту фразу — никто так и не смог пояснить ее. Обычно все заканчивается очень многозначительным видом и подёргиванием плечами. Может быть, вам удастся?
Обычная процедурная парадигма, всё те же базовые управляющие конструкции. А вот поди ж ты!
Разве в стандартах тех лет определяется значение константы TRUE? У меня почему-то в голове отложилась концепция «0=FALSE, остальное — TRUE». Если построить транслятор, который будет выдавать результатом 1 > 0, скажем, 10 — разве это будет отклонением от стандарта?
Может быть, в этом разница.
Эм, я не совсем правильно выразился. Да, 0, но просто в последствии там еще потребуются атомы при инциализации графики, и initialization какого-то из модулей просто вылетает с out of resources. Не помню последовательность, но после controls еще что-то графическое будет инициализироваться точно.
Промахнулся с ответом, извините — внизу простыня -вторая часть ответа.
В MSDN сказано, как я цитировал в посте:
Атомы вообще или именно RWMовские?
На WS2008 нет очистки, мы именно на 2008м увидели это впервые. И атомы накапливались там не один день.
Это тянется, наверняка, чуть не с 1.0. В третьей версии атомы такие же, насколько я помню из обсуждения этой проблемы. Так что тогда они экономили ресурсы
Ну, как вам сказать — сообщение-то это VCL не нужно, но вот приложение не запустится. Вообще.
Я, к сожалению, не могу этого подтвердить. MSDN утверждает, что RWM атомы живут до конца сессии, и именно это я наблюдаю.
Это действительно тривиальный код — имея под руками SDK .h заголовки, процедура перехвата пишется за пол-часа.
Готовое решение можно посмотреть здесь: проект uall.
Или просто гуглить по «delphi iat hook», первые 3 результата — вполне.
Свой код привести не могу, часть коммерческого продукта, извините.
Сам код перехватчика в простейшем варианте примерно таков:
Но его можно допилить для повышения эффективности.
Так да — строку
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
Надо заменить на
RM_GetObjectInstance := RegisterWindowMessage(PChar('ControlAtomString'));
Если кто-то соберется перекомпилировать библиотеки, могут понадобиться ключи для system.pas и подобных:
dcc32.exe system.pas sysinit.pas strings.pas -JP -M -Y -Z -$D- -0 > sysbuild.log