Предисловие
В последние несколько недель работы меня беспокоила проблема с головной болью, то есть элемент управления ActiveX, написанный на VB6, имеет множество странных проблем в среде Delphi. После многих перипетий я, наконец, перерыл почти все форумы и информацию. , нашел решения проблем, возникающих в разных версиях Delphi.
Одно из необъяснимых фатальных исключений в Delphi5
Для начала давайте посмотрим на странное поведение элементов управления ActiveX, написанных на VB под Delphi5.
Например: мы использовали VB для написания элемента управления UserTest (для простоты мы экспортируем только один класс — пользовательский элемент управления), свойства TestName и метода TestMethod. Затем скомпилируйте его в ActiveX-элемент, зарегистрируйте и импортируйте в среду разработки Delphi5 (если что-то непонятно по вышеописанным шагам, проверьте различные справочные материалы, там должны быть стандартные ответы), пока вроде все нормально.
Затем мы привыкли перетаскивать элементы управления на форму, изменять их размеры и присваивать значения свойствам в окне свойств или то же самое в коде. Это очень нормально и просто в использовании. Однако здесь возникает проблема: если вы с энтузиазмом вызовете этот TestMethod, вы получите странное исключение «OleError800a01a9», а затем программа закроется. К сожалению, вы не сможете отследить это исключение ни в VB, ни в VB. в VB Конечно, если вы хорошо разбираетесь в сборке, вы можете шаг за шагом следовать окну отладки Delphi...
Когда я впервые столкнулся с этой проблемой, я почти разозлился, потому что ни у Microsoft, ни у Borland не было ни объяснения ошибки, ни какой-либо информации, которую можно было найти. Мне пришлось зайти на несколько форумов, которые я часто посещал, конечно же, самым важным из них был CSDN, и искать похожие вопросы в версии VB и версии Delphi. К сожалению, были только похожие вопросы, но не было ответов. Крупный заказчик, использующий эту разработку. инструмент, протестировав почти все инструменты разработки и среды разработки под Windows (включая десктоп и WEB), я забыл о Delphi.
За оставшиеся два дня я почти объездил весь мир, обзванивая всех своих друзей и спрашивая, знают ли специалисты Delphi об этой ситуации. Наконец, я нашел ссылку из Google. К сожалению, я забыл ее точное местоположение. , но у меня получился почти Волшебный метод (так его называет первооткрыватель):
Эту проблему можно решить методом ручного изменения файла библиотеки типов прокси XXX_TLB.PAS (где XXX относится к имени класса элемента управления), созданного Delphi после импорта элемента управления VBActiveX. Пример:
Существует элемент управления UserControl1, написанный на VB. После его импорта в Delphi создаются два файла. Один из них, UserControl1_TLB.PAS, — это файл, который мы хотим изменить.
Найдите что-то подобное в файле
FintF:_UserControl1;
FunctionGetControlInterface:_UserControl1;
и
PROpertyControlInterface:_UserControl1readGetControlInterface;
GetControlИнтерфейс;
а также
процедураTUserControl1.CreateControl;
процедураDoCreate;
начинать
Finf:=IUnknown(OleObject)as_UserControl1;
Конец;
Начинать
IfFinf=nilthenDoCreate;
Конец;
ФункцияTUserControl1.GetControl1Interface:_UserControl1;
Начинать
СоздатьКонтроль;
Результат:=Финфл;
Конец;
Обратите внимание: все _UserControl1, отмеченные здесь красным, должны быть заменены на _UserControl1Disp. Если компиляция не удалась, замените все _UserControl1, указанные в предупреждении о компиляции, на _UserControl1Disp и скомпилируйте таким образом при вызове метода управления. Указанная выше фатальная ошибка не возникнет. происходить.
Спасибо за это великое открытие, я могу описать его только так, иначе я мог бы так и застрять в этом кругу, или мне пришлось бы использовать другой инструмент для повторной разработки этого элемента управления (я не представляю, сколько это будет работы). , и Или у него могут быть другие проблемы совместимости).
Delphi5 необъяснимое фатальное исключение 2
Однако Delphi не отпустил меня после того, как я обошел это ограничение. Вскоре заказчик обнаружил еще одну неприятную проблему. В среде разработки каждый раз при закрытии формы, содержащей элемент управления, во время выполнения появлялось исключение. не произойдет в скомпилированном приложении. Хотя это не повлияет на использование конечными пользователями, это большая проблема для разработчиков. Затем я попробовал это, используя приведенный выше пример, и обнаружил, что этого не произошло. (Я тогда сошел с ума. Вероятно, это было вызвано каким-то несовместимым использованием в коде. Было крайне страшно узнать, являются ли десятки тысяч строк кода регулярными за день.) Я разозлился и заблокировал управление в Весь код под моим контролем, остался только сам пользовательский интерфейс, а потом произошло что-то странное, я не писал никакого кода, но. Эта ошибка по-прежнему возникает при загрузке моего элемента управления, что меня радует и удивляет. Самое приятное, что эта проблема не имеет ничего общего с моим кодом, поэтому ее будет гораздо легче найти. Удивительно то, что она включает только перетаскивание. отказ от нескольких стандартов в элементах управления VB может привести к таким ужасным ошибкам. Конфликт между Delphi5 и VB6 на самом деле не так уж и глубок. В течение следующих двух часов я продолжал удалять элементы управления в интерфейсе, чтобы проверить, кто вызвал это фатальное исключение.
Через 2 часа я вздохнул с облегчением и обнаружил проблему. Основная проблема такова:
Если вы используете контейнерные элементы управления, такие как Frame и PictureBox (которые могут содержать внутри другие элементы управления) в пользовательских элементах управления VB, вы не сможете добавлять к этим элементам управления элементы без окон, такие как Label, Line и Image (то есть элементы управления Window, они рисуются VB в реальном времени во время выполнения), в противном случае вы получите отчет об ошибке, подобный приведенному выше.
Скрытые элементы управления ActiveX в Delphi6 и 7
Именно из-за ужасного опыта работы с Delphi 5 я счел необходимым проверить, существует ли та же проблема в Delphi 6 и 7 (предыдущие версии больше не нужны, поскольку пользователей очень мало, а Delphi 8 официально не выпущена) пока нет, поэтому пока не рассматриваем). Итог: ... сколько бы раз я его не загружал, я так и не нашел тот долгожданный маленький значок на панели ActiveX. Этот результат конечно очень забавный, я даже загрузить не могу, не говоря уже о том, нормальный тест или нет.
Точно так же я искал на различных форумах и веб-сайтах и нашел больше людей, задавших подобные вопросы в CSDN, но ответ по-прежнему был нулевым. В отчаянии мне пришлось настроить параметры в каждой Delphi6 и 7...
Спустя 3 часа 15 минут и 54 секунды я нашел причину или решение этой чертовой проблемы (простите меня за такое название, я просто не выдержал), которая на самом деле очень проста.
Теперь, пожалуйста, следуйте за мной: щелкните меню «Инструменты» -> «Параметры среды» -> «Библиотека типов», мы должны найти элемент: IgnorespecialCoClassFlagsWhenImporting, выберите его, а затем выберите элемент CanCreate, поэтому теперь давайте попробуем импортировать этот плохой элемент управления ActiveX (он должен быть здесь отмечено, что если вы импортировали его один раз, удалите два сгенерированных файла, файлы .dcr и .pas, иначе он не будет обновлен). Если на этот раз вы все еще не можете найти элемент управления в столбце ActiveX, тогда вам придется позвонить в Microsoft или Borland и спросить, когда они смогут пожениться, ха-ха!
(Также вышеописанные ошибки, появившиеся в Delphi5, не были обнаружены в Delphi6 и 7)
Моя тестовая среда:
Win2K
Delphi5Обновление1
Delphi6Update2
Делфи7