A las wnas. I need you!
Estoy liado en el curro ampliando un componente ActiveX que hice en su momento (en el 2002...).
Consistía en un control de usuario donde incrusté un componente gráfico (Nevron). El entorno en el que se utiliza ese ActiveX es un RAD bastante desconocido y con ciertas limitaciones a la hora de manejar ActiveX. De ahí el no poder manejarlo directamente (más que por limitación, por incomodidad) y el tener que encapsularlo en un ActiveX porgramado en VB6.
El caso es que en su momento, programé un formulario genérico dentro de este RAD que se comunicaba con el ActiveX con el fin de manejarlo y realizar diferentes cambios en las propiedades del gráfico. La comunicación la establecí mediante el envío de mensajes (API SendMessage) desde el ActiveX hacia el formulario. (Sí , parece una forma rara de conectarse, pero más tarde entenderéis el porqué xDD).
El caso es que en esta revisión y ampliación del ActiveX, he cambiado de filosofía y he decidido que esa paleta o página de propiedades esté dentro del ActiveX y sea un formulario VB6. Con lo cual digamos que todo se queda en casa. Aparentemente la comunicación es mucho más fácil.
Con lo cual tengo lo siguiente:
- Un control de usuario con el componente gráfico incrustado.
- Un formulario con una variable global pública del tipo del control de usuario para poder comunicarme con el control de usuario.
Para poder comunicarme desde el formulario hasta el control de usuario, antes de llamar al formulario, referencio la variable pública hacia el objeto 'Me' del control de usuario.
Sin embargo, en vez de crear un nuevo objeto formulario y lanzarlo dentro del control de usuario, lo que hago es crear un objeto formulario y establezco una referencia (puntero, digamos) hacia él. Me explico:
En vez de poner:
dim frm as Form
Set frm = new frmPropiedades
Pongo lo siguiente:
dim frm as Form
Set frm = frmPropiedades
Con esto consigo que si tengo varios ActiveX pegados en mi aplicación, todos compartan el mismo formulario. De esta forma, consigo que si el usuario pincha en un gráfico, el formulario lanzado "cambie de forma" (cambio el ZOrder de varios controles Frame para cada tipo de gráfico) y así no tenga que lanzar una página de propiedades para cada gráfico. El efecto es muy muy vistoso.
En la primera versión del componente esto lo lograba gracias al paso de parámetros por SendMessage. Ahora esta solución me pareció muy buena.
Y ahora llega lo peor...: Este punto entorno RAD en cual llevo programando ya 9 años y del cual me he convertido en un puto gurú (a parte de conocer a algunos del equipo de I+D que lo desarrollan), da ciertos errores fatales cuando los ActiveX están insertados dentro de un formulario MDI. Y esto es debido a que al no descargar el ActiveX de memoria, por mucho que yo en el terminate del control ponga mis objetos a Nothing, estos nunca se liberan.
Si la aplicación fuera SDI, funciona perfectamente. De hecho estas 2 semanas de trabajo lo he probado en SDI hasta la saciedad con éxito. Pero en MDI "CASCA".
Si cambio la forma de referenciar el formulario y creo un objeto formulario por cada instancia de ActiveX, no existe este problema. Pero al tener una referencia o puntero esto me impide lograr un formulario que cambia de forma y habría que lanzar una página de propiedades para cada gráfico. Algo que todo Dios tiene en sus aplicaciones, eso sí, pero que a mí me gustaría seguir manteniendo mi paleta "polimórfica" que es flotante (gracias a la llamada de una API) y cambia las propiedades de sus controles en función del gráfico en el que pinches.
Después de varios palos de ciego, se me ha ocurrido no referenciarlo y crear un objeto formulario por cada instancia del ActiveX y, de alguna forma, guardar referencias a esos objetos para luego al pinchar en el control, pasar la referencia del control de usuario al formulario que esté lanzado. Pero no se me ocurre como hacerlo. Si alguien sabe como hacer esto, agradecería su aporte. Ya se que una solución sería guardar en una colección todos los objetos formularios que se crean por cada instancia del activex. Es decir, en el evento Initialize del componente, a la par que creo el objeto formulario, guardarlo en una colección, pero en el fondo tampoco le veo futuro ya que el puto entorno este, crea una instancia en tiempo de diseño y otra en tiempo de ejecución, con lo cual se monta la de Dios.
Lo que subyace debajo de este problema es la problemática Threads, COM y un sinfin de problemas típicos cuando desarrollas un componente un poco más allá de lo normal.
Creo que volveré a la comunicación mediante SendMessage que es más primitiva pero más robusta.
Si tenéis una idea mejor... Aunque realmente es un hilo para llorar, no para otra cosa xDDD.
Thx
P.D.: Quizás después de releerme el hilo, he complicado más las cosas. Mejor planteo el asunto de forma más sencilla:
¿Cómo comunicaríais un control de usuario con un formulario dentro del mismo proyecto ActiveX?
Gracias xDDD