Prefacio
En las últimas semanas de trabajo, tuve un problema de dolor de cabeza, es decir, el control ActiveX escrito en VB6 tiene muchos problemas extraños en el entorno Delphi, después de muchos giros y vueltas, finalmente busqué en casi todos los foros e información. , encontró soluciones a problemas que ocurren en diferentes versiones de Delphi.
Una de las inexplicables excepciones fatales en Delphi5
Primero, echemos un vistazo al extraño comportamiento de los controles ActiveX escritos en VB bajo Delphi5.
Por ejemplo: utilizamos VB para escribir un control UserTest (para simplificar, solo exportamos una clase, el control de usuario), una propiedad TestName y un método TestMethod. Luego compílelo en un control ActiveX, regístrelo e impórtelo al entorno de desarrollo Delphi5 (si no está claro acerca de los pasos anteriores, consulte varios materiales de referencia, debe haber respuestas estándar), hasta ahora, todo parece normal.
Entonces, estamos acostumbrados a arrastrar y soltar controles en el formulario, cambiar su tamaño y asignar valores a las propiedades en la ventana de propiedades, o lo mismo en el código. Es muy normal y fácil de usar. Sin embargo, aquí viene el problema. Si llama a TestMethod con entusiasmo, obtendrá una extraña excepción "OleError800a01a9" y luego el programa se cerrará. Desafortunadamente, no podrá rastrear esta excepción en Delphi ni en VB. en VB Por supuesto, si eres bueno ensamblando, puedes seguir la ventana de depuración de Delphi paso a paso...
Cuando encontré este problema por primera vez, casi me enojé porque ni Microsoft ni Borland tenían ninguna explicación para el error, ni información que encontrar. Tuve que ir a varios foros que frecuentaba, por supuesto el más importante era CSDN, y busqué preguntas similares en la versión VB y en la versión Delphi. Desafortunadamente, solo hubo preguntas similares pero no hubo respuestas. Un gran cliente que utiliza este desarrollo. herramienta, después de probar casi todas las herramientas y entornos de desarrollo en Windows (incluidos el escritorio y la WEB), me olvidé de Delphi.
En los dos días restantes, casi corrí por todo el mundo, llamando a todos mis amigos y preguntando si los expertos de Delphi conocían esta situación. Finalmente, encontré un enlace de Google. Desafortunadamente, ahora he olvidado la ubicación exacta de ese enlace. , pero obtuve un método casi mágico (así lo llama el descubridor):
Un método para modificar manualmente el archivo de biblioteca de tipos de proxy XXX_TLB.PAS (donde XXX se refiere al nombre de clase del control) generado por Delphi después de importar el control VBActiveX puede resolver este problema. Ejemplo:
Hay un control UserControl1 escrito en VB Después de importarlo en Delphi, se generan dos archivos. Uno de ellos, UserControl1_TLB.PAS, es el archivo que queremos modificar.
Encuentra algo como esto en un archivo.
FintF:_UserControl1;
FunciónGetControlInterfaz:_UserControl1;
y
PRopertyControlInterface:_UserControl1readGetControlInterface;
GetControlInterfaz;
así como
procedimientoTUserControl1.CreateControl;
procedimientoDoCreate;
comenzar
Finf:=IUnknown(OleObject)as_UserControl1;
Fin;
Comenzar
IfFinf=nilthenDoCreate;
Fin;
FunciónTUserControl1.GetControl1Interfaz:_UserControl1;
Comenzar
CrearControl;
Resultado:=Finfl;
Fin;
Tenga en cuenta: todos los _UserControl1 marcados en rojo aquí deben reemplazarse con _UserControl1Disp. Si la compilación no tiene éxito, reemplace todos los _UserControl1 informados en la advertencia de compilación con _UserControl1Disp y compile de esta manera al llamar al método de control. ocurrir.
Gracias por este gran descubrimiento, solo puedo describirlo así; de lo contrario, es posible que todavía esté atrapado en este círculo o tendría que usar otra herramienta para volver a desarrollar este control (no puedo imaginar cuánto trabajo supondrá). y O puede tener otros problemas de compatibilidad).
Delphi5 excepción fatal inexplicable 2
Sin embargo, Delphi no me dejó ir después de que eludí esta restricción. Pronto, el cliente descubrió otro problema problemático en el entorno de desarrollo: aparecía una excepción cada vez que se cerraba el formulario que contenía el control en tiempo de ejecución. No sucede en la aplicación compilada. Aunque no afectará el uso de los usuarios finales, es un gran problema para los desarrolladores. Luego lo intenté usando el ejemplo anterior y descubrí que no sucedió. (Me volví loco en ese momento. Esto probablemente se debió a algún uso incompatible en el código. Fue extremadamente aterrador descubrir si decenas de miles de líneas de código eran regulares en un día). Me enojé y bloqueé el control en Mi control. Todo el código, dejando solo la interfaz de usuario en sí, y luego sucedió algo extraño, no escribí ningún código, pero Este error todavía ocurre al cargar mi control, lo cual me deja feliz y sorprendido. Lo feliz es que este problema no tiene nada que ver con mi código, por lo que será mucho más fácil de encontrar. Lo sorprendente es que solo implica arrastrar y. eliminar algunos estándares en VB Controls en realidad puede causar errores tan horribles. El conflicto entre Delphi5 y VB6 realmente no es tan profundo. En las siguientes 2 horas, continué eliminando controles en la interfaz para probar quién causó esta excepción fatal.
Después de 2 horas, suspiré aliviado y encontré el problema. El problema fundamental es:
Si utiliza controles de contenedor como Marco y Cuadro de imagen (que pueden contener otros controles en su interior) en controles de usuario de VB, no podrá agregar controles sin ventana como Etiqueta, Línea e Imagen a estos controles (es decir, sin controles de ventana, VB los dibuja en tiempo real durante el tiempo de ejecución); de lo contrario, obtendrá el informe de error como el anterior.
Controles ActiveX ocultos en Delphi6 y 7
Precisamente debido a la horrible experiencia con Delphi 5, todavía me pareció necesario probar si existe el mismo problema con Delphi 6 y 7 (las versiones anteriores ya no son necesarias porque hay muy pocos usuarios y Delphi 8 no se ha lanzado oficialmente). todavía, por lo que no está disponible por el momento no se consideran). El resultado es: ... no importa cuántas veces lo cargue, nunca encuentro ese pequeño ícono tan esperado en la barra ActiveX. Por supuesto, este resultado es muy divertido. Ni siquiera puedo cargarlo, y mucho menos si la prueba es normal o no.
De manera similar, busqué en varios foros y sitios web y encontré más personas haciendo preguntas similares en CSDN, pero la respuesta aún era cero. Desesperado, tuve que ajustar las opciones en cada Delphi6 y 7...
Después de 3 horas, 15 minutos y 54 segundos, encontré la causa, o la solución, de este maldito problema (perdónenme por llamarlo así, simplemente no pude soportarlo), que en realidad es muy simple.
Ahora síganme: haga clic en el menú Herramientas->EnvironmentOptions->TypeLibrary página, deberíamos encontrar un elemento: IgnorespecialCoClassFlagsWhenImporting, selecciónelo y luego seleccione el elemento CanCreate, así que ahora, intentemos importar ese control ActiveX deficiente (debería ser Tenga en cuenta aquí que si lo ha importado una vez, elimine los dos archivos generados, los archivos .dcr y .pas; de lo contrario, no se actualizará). Si esta vez todavía no puedes encontrar el control en la columna ActiveX, entonces tienes que llamar a Microsoft o Borland y preguntar cuándo pueden casarse, ¡jaja!
(Además, los errores anteriores que aparecieron en Delphi5 no se encontraron en Delphi6 y 7)
Mi entorno de prueba es:
Win2K
Actualización 1 de Delphi5
Delphi6Actualización2
Delfos7