Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Saber cuando un Form hace un Paint (https://www.clubdelphi.com/foros/showthread.php?t=48109)

José Luis Garcí 15-09-2007 17:19:35

Saber cuando un Form hace un Paint
 
Es posible capturar el paint de un form (OnPaint) desde un com ponente, ya que el WM_Paint no lo hace?

paldave 15-09-2007 18:45:59

Pues claro que es posible, ¿que no es posible en nuestro amado Delphi? :)
Puedes capturar el evento OnPaint del Form desde tu componente:
Código Delphi [-]
type
  TMiComponente=class(ClaseDeLaQueDeriva);
  private
    procedure FormPaint(Sender: TObject);
  public
    constructor Create(AOwner:TComponent);override;
  end;
...
constructor TMiComponente.Create(AOwner:TComponent);
begin
  inherite Create(AOwner);
  TForm(GetParentForm(Self)).OnPaint:=FormPaint;
end;

procedure TMiComponente.FormPaint(Sender:TObject);
begin
  //aquí tu código
end;

José Luis Garcí 15-09-2007 22:06:07

PAldave, gracias por tu respuesta pero me da un error de incompatible tipos Tcontrol con mi Tcomponent.

De todas maneras, me gustaria saber si vale para el resto de los eventos.

paldave 16-09-2007 00:26:21

Vale para todos los eventos.
El error se debe a que tu componente no es visual, es decir, deriva de TComponent y no de TControl, por lo cual no tiene un Form "padre".
La forma de solucionarlo podría ser la siguiente:
Código Delphi [-]
constructor TMiComponente.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  TForm(Owner).OnPaint:=FormPaint;
end;
debido a que los componentes no visuales tienen como propietario el formulario en el cual están.

Espero que con esto soluciones el problema.[/font][FONT=verdana,geneva,lucida,'lucida grande',arial,helvetica,sans-serif]

Saludos.

Al González 16-09-2007 01:07:51

¡Hola!

Cita:

Empezado por José Luis Garcí (Mensaje 231349)
Es posible capturar el paint de un form (OnPaint) desde un com ponente, ya que el WM_Paint no lo hace?

Hoy mientras me duchaba, por alguna divagación del pensamiento vino a mi mente el componente que estás creando (http://www.clubdelphi.com/foros/showthread.php?t=47994), el cual, supongo, es la razón de este nuevo hilo.

Win32.hlp, ese valioso archivo que todos los programadores Delphi tenemos dice sobre el mensaje wm_Paint:
Cita:

Empezado por la ayuda de la API de Windows
An application sends the WM_PAINT message when Windows or another application makes a request to paint a portion of an application's window. The message is sent when the UpdateWindow or RedrawWindow function is called, or by the DispatchMessage function when the application obtains a WM_PAINT message by using the GetMessage or PeekMessage function.

El mensaje sólo es enviado a los objetos visibles (genéricamente llamados "windows" en la API). Sean botones, cuadros de texto o formas, todos los objetos que en Delphi derivan de la clase TWinControl son susceptibles a recibir el mensaje wm_Paint. Tu componente no recibe el mensaje porque no es un control (componente visual), necesitaría ser derivado de TWinControl para que reciba dicho mensaje de manera natural.

Visto esto, la pregunta ético-técnica sería: ¿mi componente tiene que ser visual para darle cierto efecto visual a otros componentes? Estrictamente, la respuesta es no. Si quieres hacerlo fácil, adelante, deriva TCCDShadow de TWinControl y sí recibirá el mensaje, pero, a reserva de lo mucho que ignoro sobre los mensajes de Windows, me parece que no sería suficiente y quizá en algunos casos no funcione tal como se espera el método ShadowDraw.

La idea de lo que buscas es interesante (aunque todavía no logro imaginarme qué habrá de hacer exactamente el componente). Todo lo que entiendo es que le imprime cierto efecto visual a los controles que contenga la forma. Necesitaría analizarlo con un poco más de tiempo y calma para proponer alguna alternativa. Por el momento, sólo puedo invitar a otros a no dejar solo a José Luis. ¡Ánimo! :)

Un TAbrazo.

Al González. :)

P.D. Es en estos momentos cuando se echa de menos la gran disponibilidad de Román para ayudar a resolver casos de POO. Un saludo Román, esperamos verte pronto por acá. :)

José Luis Garcí 16-09-2007 09:12:56

Gracias a ambos, he de decir, que efectivamentem ene ste caso es sólo un componente visual, pero que dependiendo, del resultado que me de derivara, en posteriores componentes, visuales, y no visuales, que ire poniendo en el club, tengo en mente un buen puñado, pero soy muy lento programandolos, por que me pierdo en la OPP, tengo multitud de libros sobre delphi hasta el 6, incluyendo La Cara Oculta de DElphi 4, y no termino de allar las respuestas.

Con Delphi, mi gran problema, es el Ingles, me peleo a ratos, con el de mis 6 Delphi (2,3,4,5,6,Turbo), sólo tengo el manual en españos del 4, Son comprados Orginales, todos, exeptuando el Turbo que es free en su página, yo hasta hace unos seis años, sólo me interesaba, programar para bases de datos, hara unos 4 tube una serie de problemas en la empresa, que aún acarreo, pero en un principio, no me quedaba casi tiempo libre, ahora aunque vivo mucho mas lejos, tengo más tiempo.

Pero soy persistente, suelo trabajar con muchas cosas a la vez, llevo trabajando 24 años (desde los 16) y he aprendido muchas profesiones, y en todas ellas la tenacidad, es una cuestion que no puede fallar, me he propuesto terminar el componente, y lo hare.

Gracias por vuestra ayuda y probare los cambios expuestos.

José Luis Garcí 16-09-2007 11:48:38

No me vale el evcento Ompaint, ya que se repite multitud de veces, en un segundo.

Caral 16-09-2007 16:33:52

Hola
No me hagais mucho caso en esto, de componentes no se nada, pero leyendo un poco encontre esto:
Cita:

Como base para la elección del ascendiente, conviene hacer notar las siguientes normas:

* TComponent - El punto de partida para los componentes no visuales.
* TWinControl - El punto de partida si es necesario que el componente disponga de handles.
* TGraphicControl - Un buen punto de partida para componentes visuales que no sea necesario que dispongan de handles, es decir, que no reciban el foco. Esta clase dispone del método Paint y de Canvas.
* TCustomControl - El punto de partida más común. Esta clase dispone de window handle, eventos y propiedades comúnes y, principalmente, canvas con el método Paint.

Bueno, segun entiendo el TComponent es para componentes NO visuales, en este caso seria lo correcto.
Pero dice que TCustomControl es para el manejo del metodo Paint.
Me quede con la duda y por eso lo puse, nada mas para aprender.
Saludos

Al González 16-09-2007 20:26:42

¡Hola a todos y bienvenido de regreso Carlos!

Cita:

Empezado por Caral (Mensaje 231456)
...segun entiendo el TComponent es para componentes NO visuales, en este caso seria lo correcto.
Pero dice que TCustomControl es para el manejo del metodo Paint.
Me quede con la duda y por eso lo puse, nada mas para aprender.
Saludos

Es precisamente el punto de mi comentario anterior. El componente, estrictamente hablando no tiene que ser visual, porque su propósito es darle cierto aspecto visual a otros componentes mas no a sí mismo. El quid es atrapar algún mensaje o evento relacionado con el dibujo de los controles de la forma. Como la forma misma recibe un mensaje wm_Paint de parte de Windows, se pensó que sería buena idea tratar de interceptar este mensaje, pero entonces la pregunta fue ¿cómo? Como tú señalas, sería buena idea derivar la clase del nuevo componente de TCustomControl (no directamente de TWinControl, como sugería en mi mensaje anterior), pero no sería lo correcto, a menos que el nuevo componente sea visual en el sentido de que posea su propia área de dibujo.

Desde ayer he venido pensando que el nuevo componente podría contener dentro de sí mismo un objeto TApplicationEvents con el cual, a través de su evento OnMessage, se intercepten todos los mensajes wm_Paint que le lleguen a la aplicación y proceda en consecuencia a realizar su cometido cuando dicho mensaje vaya dirigido a la forma o a alguno de sus controles. Pero de momento no estoy seguro de si todos los mensaje wm_Paint llegan al evento OnMessage de la aplicación (TApplicationEvents.OnMessage, en este caso). Sería cosa de investigar un poco más.

De todas maneras, creo que no se pierde mucho con intentarlo. ;)

Un wm_abrazo.

Al González. :)

José Luis Garcí 16-09-2007 21:01:52

Gracias pro vuetra ayuda, lo he intentado, con un TWinControl, Con un TCustomControl, Con TImagen, no recuerso si con alguno más, pero el fallos lo comenta AI Gonzáles, es un componente no visual que realiza un efecto en los controles del form, y no un componente visual, ya que aunque lo podria mandar al fondo, el problema es si otro componentenecesitase ir al fondo, quedaria, mal.

Lo tengo medio solucionado, creando un timer en el componente, el único problema es que si el valor de interval es muy bajo, se puede llegar a notar un ligero parpadeo, y si el intervalo es muy largo, cualquier refresh, repaint, minimize, etc, que oblige a redibujar los controles, seguiria sin aparecer hasta llegar al evento OnTimer, no se si me he explicado bien.

Pronto pondre este componente, en el club, si alguien tiene la solución, como siempre es libre de modificarlo, al gusto, que para eso soy un principiante, tambien añadire los TCCDEditZoom y TCCDDBEditZoom, ya modificados,me quedan pequeños detalles, pero ha sido una semana muy dura de trabajo y llego casi todos los días tarde.

Unb pequeño detalle, los que han probado el componente, que les parece el efecto, se han dado cuenta, que ya no se han seguido introuciendo componentes para el Club, por mi parte pienso seguir, será que los compañeros, han estado muy liados.

Al González 16-09-2007 21:17:09

¡Hola José Luis!

¿Quién es AI Gonzáles? ¿Algún robot con inteligencia artificial? :D

Échale un vistazo a esta sección de Torry's Delphi Pages. Estuve mirando y encontré que, en algunos casos similares al tuyo, los programadores han recurrido a la sustitución del manejador del evento OnPaint de la forma (técnica que en lo personal sólo empleo como último recurso) o la sustitución de su propiedad WindowProc.

Dos ejemplos de ello son los componentes TAeroGlass y TAlphaBlendForm que ahí aparecen. Espero sirva de algo.

Hasta pronto.

Al.

José Luis Garcí 16-09-2007 21:35:16

Gracias, echando un vistazo.

basti 17-09-2007 00:03:06

Cita:

Empezado por José Luis Garcí (Mensaje 231442)
No me vale el evcento Ompaint, ya que se repite multitud de veces, en un segundo.

El evento OnPaint se repite cada vez que se tiene que repintar el form. En este caso, si pones un breakpoint en el evento onPaint, cuando vuelvas a ejecutar se volverá a parar en el breakpoint del evento. Lo mismo pasa si muestras un mensaje o cambias el valor de un label dentro del evento onPaint, que se vuelve recursivo. Por eso puede parecer que se ejecuta demasiadas veces.

Creo que capturar el evento OnPaint del form sería la mejor manera de solucionar el problema del pintado del componente. En los ejemplos que te mostró Al González utilizan el OnPaint para cambiar la apariencia de los controles.

José Luis Garcí 17-09-2007 21:54:59

Como hacer un breakpoint del evento en el código?


La franja horaria es GMT +2. Ahora son las 00:37:29.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi