FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
||||
|
||||
Cómo codificar en el evento (incluso asignado) de un componente
Hola,
Tengo un problema, o, por mejor decir, una inquietud, puesto que no sé si resolviendo esta se creará aquél. Estoy pensando en crear un sencillo componente que habría de heredar de un "TWebBrowser". Para lo que quisiera conseguir, necesitaría de codificar en su evento "OnBeforeNavigate2". Bien. O mal. El caso es que llego hasta crear un método capaz de responder a dicho evento, de tal forma que cuando creo una instancia de la clase "TDecWebBrowser" pueda hacer algo más o menos así: O sea, al crear el componente asigno a su evento "OnBeforeNavigate2" el método privado del mismo componente, que es en donde necesito codificar determinadas cuestiones. En donde ahora pone "TODO". ¿Y? Pues que si cuando hago uso del componente asigno al evento "OnBeforeNavite2" un manejador del evento, adiós al que asigné cuando se creó el componente. ¿Se entiende? Si algo no se entiende, por favor, no dejéis de decirlo y trataré de ofrecer la información tan precisamente como pueda. Gracias de antemano a todos y saludos. P.D. No corre ninguna prisa. |
#2
|
||||
|
||||
Se supone, que el evento OnBeforeNavigate2 es del propio TWebBrower, entonces, tu componente ha de quitarlo de la zona published. Simplemente declarandolo en tu componente en la zona Private.
A continuación creas tu propio evento OnBeforeNavigate y lo haces published. Y este nuevo evento será el que vea el usuario de tu componente, es decir: El usuario programador que use tu componente no sabrá que existe AntesDeNavigar (ni falta que le hace) . Espero te sirva.
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#3
|
|||
|
|||
Cita:
Bueno, el problema que se te plantea se resolvería adecuadamente si tuvieras acceso al método supuestamente protegido y supuestamente llamado DoBeforeNavigate o algo así, virtual claro, que no sé si existe. Como supongo que ya lo has buscado y no has encontrado nada parecido, lo único que se me ocurre es un pequeño truco, que no evita que se pueda machacar tu evento en tiempo de ejecución, pero que quizás en la práctica resulte suficiente (si vas a utilizar tú el componente, no es problema pues sabes lo que no debes hacer, si es un componente para terceros tendrá una puerta trasera donde puedan machacar tu código de forma involuntaria): Sobrescribes el método Loaded, y ahí almacenas en una variable del tipo adecuado el evento que haya sido fijado en tiempo de diseño:
En el método AntesDeNavegar haces una llamada a EventoAnterior, claro. Bueno, es algo chapucilla, pero puede servirte. Saludos
__________________
Guía de Estilo |
#4
|
||||
|
||||
Hola,
Gracias a ambos por responder, en primer lugar. Tomando la manera que dice Lepe, queda algo pendiente y es que no se acaba de quitar del "inspector de objetos" el evento "OnBeforeNavigate2", aun cuando lo declaro como una propiedad privada con el fin de ocultarlo, precisamente,... ¿qué estoy olvidando? Es decir, el tema parece ir bien, pero, ahora en el "inspector de objetos" tengo dos eventos "OnBeforeNavigate" (que yo preparo en el componente) y "OnBeforeNavigate2" (que ya incorpora el componente de que heredo, y acaso sería bien ocultar)... Además, si el usuario asigna algún método a este último evento, adiós al primero... claro está... ¿Cómo oculto, pues, el evento "OnBeforeNavigate2"? Gracias de nuevo a ambos. El componente no es ninguna maravilla, pero, si llego a darle cabo, más o menos, ya sabéis que lo incluiré en DecComp. Gracias otra vez. |
#5
|
||||
|
||||
Cita:
En la mayoria de los casos se debe ir una clase mas arriba, antes que se haga publico la propiedad, pero en este caso no tienes una clase más arriba que te sirva. La opción que te queda es sobreescribir la propiedad. Aca te hice un ejemplo de como sería:
creo que con esto debería funcionar sin problemas Suerte
__________________
[Crandel] |
#6
|
||||
|
||||
Hola,
A quien le pueda resultar interesante, aquí tienen una posible forma de ocultar propiedades, dictada por Neftali. En todo caso, Crandel, lo que propones funciona exactamente como esperaba. Muchísimas gracias a todos. De verdad. |
#7
|
||||
|
||||
Hola,
Bueno, pues, he llamado al engendro TDecBrowser y pueden conseguirlo aquí mismo. Gracias de nuevo a todos. |
#8
|
||||
|
||||
No sé, no sé. A mi como que me da más algo del estilo:
Si inherited se llama antes o después ya dependerá de tus necesidades específicas. // Saludos |
#9
|
||||
|
||||
Cita:
Lo que comentas lo pense al prpicipio, pero el tema es que el método InvokeEvent es llamado muchas veces al parecer, lo cual se estaria llamando constantemente a nuestro método override, para no hacer nada. Si la idea es capturar este único evento, lo haria con mi propuesta, si se quiere capturar varios más, lo haria a la forma recdomendada por roman.
__________________
[Crandel] |
#10
|
||||
|
||||
Cita:
¿Te imaginas cuántas veces se llama a WndProc? Pero esto no es óbice para no redefinirlo de ser necesario incluso si el comportamiento añadido es muy poco. Por otra parte, aunque es cuestión de puntos de vista, los métodos y/o propiedades de una clase no debieran esconderse (aun suponiendo que realmente se puede); la herencia de clases se supone que está para añadir funcionalidad no para quitarla. // Saludos |
#11
|
||||
|
||||
Cita:
Cita:
__________________
[Crandel] Última edición por Crandel fecha: 03-11-2005 a las 07:48:52. |
#12
|
||||
|
||||
Cita:
// Saludos |
#13
|
||||
|
||||
Cita:
En cuanto a lo demás que habeís hablado.... simplemente me callo saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#14
|
||||
|
||||
Hola,
Probé, probé, previamente, con el método "InvokeEvent", lo que ocurre que es no llegué a dar con una forma de usarlo, puesto que solamente me fijé en el método "InvokeEvent" de la clase "TInternetExplorer". Eso me confundió y no llegué a ver que la clase "TWebBrowser" también tiene su "InvokeEvent". De momento, para lo que es, se queda como está, pero, de todos modos, muchas gracias a todos por vuestras aportaciones, valiosas todas ellas. |
#15
|
||||
|
||||
Hola,
Solamente añadir que anoche me dormí pensando en esto (vaya una vida más alucinante la mía, últimamente) que dijo Crandel: Cita:
Y es que, ¿de verdad esta instrucción no parece una maravilla, por decirlo así? Aún no he conseguido desentrañarla, y puede que no lo haga nunca, pero, desde luego, trataré de quedarme con la idea. En fin, trataré de quedarme con todo lo que se va diciendo por aquí, ¡porque lo vale! ¿Os he dado ya las gracias? Pues ahí van otra vez: a todos, muchas gracias. |
#16
|
||||
|
||||
Cita:
Si necesito heredar de un componente y la propiedad Color (por decir una) no tiene sentido en mi componente heredado, no creo que haya que dejarla visible/accesible. ¿Qué pasa si esa propiedad altera el comportamiento de tu componente de una forma no deseada? ¿Añado código para inutilizarla? Pero estonces estaré añadiendo código para deshabilitar una propiedad que sí veo y tengo accesible, pero que no necesito... ¿raro no?
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
#17
|
||||
|
||||
Hola,
Bueno. Pues el componente está muy bien, o eso me parece, en cuanto a que puede resultar útil, pero, me encuentro con un problema que paso a explicar. Se trata de las acciones que pueden asociarse al componente. Puede asociarse con el componente "DecBrowser" un componente "TActionList". No hay problema en hacerlo, y tampoco con el componente, es decir, que todo parece ir bien. El problema está en quitar el componente de un formulario en tiempo de diseño. Añádase en un formulario vació el componente "DecBrowser"; añádase también un "TActionList" al formulario; asígnese este último componente a la propiedad "Acciones" del "DecBrowser"; quítese del formulario ahora el "TActionList", y, a continuación, trátese de quitar el componente "DecBrowser" del formulario... Perdón por las "violaciones de acceso", "errores abstractos" y demás. No era mi intención, se lo juro. Estoy probando cosas. Por ejemplo, si a la hora de crear la variable que contendrá la propiedad "Acciones" hago algo así: En lugar de algo como esto otro: La cosa parece pintar mejor, sin embargo, aún no he dado con la solución para el problema que he comentado arriba. Sigo en ello, a ver si soy capaz. Cualquier ayuda será bienvenida. Por cierto, en el código del componente actualmente hay algo como esto: Y lo he cambiado por algo así: Con sus correspondientes métodos: Pero, como pueden ver, son algo superfluos los métodos de arriba, puesto que para ese viaje no hacían falta tantas alforjas, como suele decirse. Pero, es que esto otro, aunque compilar compila, no funciona: Me aparece tal que este error: Cita:
Última edición por dec fecha: 03-11-2005 a las 14:29:22. Razón: Corrección del texto. |
#18
|
||||
|
||||
Mientras roman llega y no llega, doy mi opinión .
Tu no tienes que crear Facciones ni mucho menos. Delphi se encarga de crear el TActionList cuando lo agregas a tu form y "crea" los editores y formularios (editor de propiedades). Y también destruirá el TActionList cuando lo quites en tiempo de diseño de tu forma. Tú lo único que tienes que hacer es asignar el actionList y cuando necesites acceder, comprobar que no es nil.
y dejar tu propiedad como: Si se quita el TActionList del form supongo (comprobar en delphi (1*)) que el IDE le asigna nil a tu propiedad Facciones, y como en tu código siempre compruebas que FAcciones es distinto de nil (con assigned si quieres), tú componente jamás dará violaciones de acceso. (1*) - Para comprobar este punto, te sirve mejor el métod SetAcciones, para poner un punto de ruptura y comprobar que es realmente nil A menos que tu componente lleve una propiedad Acciones, que al pulsar en los 3 puntitos, deba aparecer el editor de propiedades de un TActionList. Este método me parece un poco extraño, pero es la única explicación de hacer un TActionList.Create dentro de tu componente. No sé si me he explicado bien. saludos
__________________
Si usted entendió mi comentario, contácteme y gustosamente, se lo volveré a explicar hasta que no lo entienda, Gracias. |
#19
|
||||
|
||||
Hola,
Lo he podido solucionar (de momento, al menos, parece funcionar bien, no se produce el error antes mencionado y el componente va también bien en tiempo de ejecución) sobreescribiendo el método "Notification" de "TComponent". Primeramente creo una variable privada "FAcciones" de tipo "TCustomActionList". Luego una propiedad "Acciones" del mismo tipo, y que va a leer y a escribirse en "FAcciones". En el constructor del componente hago lo siguiente: Creo la instancia de "TActionList" en "Application", porque, de no hacerlo así, de hacerlo en "Self" (el propio componente) en el "inspector de objetos" de Delphi la propiedad no queda muy bien al comienzo. Puede verse. No es el caso ahora. En el destructor del componente libero la variable "FAcciones" sin problemas, tal que así: Y el quid de la solución está en el método "Notification", como queda dicho, sobreescrito para que quede de este modo: A lo mejor es una burrada. Lo que estoy haciendo es comprobar que el componente que se quita de mi componente, valga la redundancia, es "FAcciones", si es así notifico su eliminación al IDE de Delphi (supongo algo así, no estoy muy puesto, para qué nos vamos a engañar) y a continuación creo de nuevo una instancia de "FAcciones", por si el usuario quiere añadir de nuevo un componente "TActionList". Eso era lo que se apreciaba antes con error: al quitar el "TActionList" del componente "DecBrowser" en tiempo de diseño podía verse junto con el mensaje de error (Access violation, Abstract error...) cómo "desaparecía" la propiedad "Acciones" del "inspector de objetos"... En fin. No sé qué tal la solución. Ahora revisaré cuanto dice Lepe, pues seguro será interesante. Ya podéis descargar, por cierto, el componente actualizado en mi página Web personal: dec.clubdelphi.com. |
#20
|
||||
|
||||
Hola,
He probado lo que sugieres Lepe, pero, o bien no llegué a hacerlo del todo como se debe, o, en cualquier caso, no podía hacerlo: no podía ni ubicar siquiera el componente en el formulario: ¿Violación de acceso? Ahora mismo no recuerdo el problema en concreto... He preparado (*) una demostración de que el componente funciona como se espera, más o menos, tanto en tiempo de diseño como en ejecución, si bien se mira. Es algo pesado (como 1 MB) pero con las conexiones que tenéis de 100 MB debe ser pan comido para vosotros. Demostración del componente DecBrowser (formato Flash, 1 MB apróx.) (*) Con la ayuda del programa Wink, estupendo, por otro lado, hay que decirlo. |
|
|
|