Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-05-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 24
marto Va por buen camino
Cita:
Empezado por Sonic
Cuando digo que mi componente lo quiero hacer VCL lo que quiero decir es que lo quiero incrustar en las barras de herramientas, ahora mismo lo tengo en la barra Samples (lo llamo TSRichEdit y hereda obviamente de TRichEdit), disponible para poder ser arrastrado a la aplicación de cualquier usuario.
Vale, ahora te entiendo. Por lo que dices, imagino que lo que ahota tienes es un component template, que lo que hace es pegar el código asignado a los eventos el form donde lo sueltas. Lo que quieres hacer es un componente nuevo que encapsule ese comportamiento.

Cita:
Empezado por Sonic
Lo que yo quiero es que mi componente, cuando alguién lo "pegue" en su aplicación responda al evento OnSelectionChange, primero mediante mi funcion y despus mediante la que él tenga especificada en el Inspector de Objetos.
Ok, entonces tienes que cambiar un poco la filosofía. Te pongo un ejemplo en Delphi porque el CB no lo tengo a mano, pero la traducción no es complicada.
Código Delphi [-]
unit richEdit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ComCtrls, Dialogs;
type
  trichEdit1 = class(trichedit)
  private
    { Private declarations }
  protected
    //este método se declara en TCustomRichEdit y es el encargaado de lanzar el evento
    procedure SelectionChange; override;
  public
    { Public declarations }
  published
    { Published declarations }
  end;
procedure Register;
implementation
procedure Register;
begin
  RegisterComponents('NexContr', [trichEdit1]);
end;
{ trichEdit1 }
procedure trichEdit1.SelectionChange;
begin
  ShowMessage('hola');
  //Aquí va tú código, que se ejecutará antes que el que haya asignado el usuario
  inherited;
  //como llamamos a la versión de la superclase, ésta ya se encarga de activar el
  //manejador del evento si se ha asignado alguno
end;
end.
__________________
E pur si muove
Responder Con Cita
  #2  
Antiguo 27-05-2004
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 27
__cadetill Va por buen camino
mmmm, Marto, perdona, pero..... de esta manera creo que no saltará el evento si no lo tiene asociado en el componente, no?

PD: lo digo con la voca xica, que no lo he probado
Responder Con Cita
  #3  
Antiguo 27-05-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 24
marto Va por buen camino
Cita:
Empezado por cadetill
mmmm, Marto, perdona, pero..... de esta manera creo que no saltará el evento si no lo tiene asociado en el componente, no?
Copia y pega el código, lo pruebas y luego me cuentas
__________________
E pur si muove
Responder Con Cita
  #4  
Antiguo 27-05-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 24
marto Va por buen camino
Una pista...

Código Delphi [-]
procedure TCustomRichEdit.SelectionChange;
begin
  if Assigned(OnSelectionChange) then OnSelectionChange(Self);
end;
Esa es la implementación del método en TCustomEdit.
El método se llama al capturar el mensaje correspondiente de windows:
Código Delphi [-]
procedure TCustomRichEdit.CNNotify(var Message: TWMNotify);
begin
  with Message do
    case NMHdr^.code of
      EN_SELCHANGE: SelectionChange;
      EN_REQUESTRESIZE: RequestSize(PReqSize(NMHdr)^.rc);
      EN_SAVECLIPBOARD:
        with PENSaveClipboard(NMHdr)^ do
          if not SaveClipboard(cObjectCount, cch) then Result := 1;
      EN_PROTECTED:
        with PENProtected(NMHdr)^.chrg do
          if not ProtectChange(cpMin, cpMax) then Result := 1;
    end;
end;
__________________
E pur si muove
Responder Con Cita
  #5  
Antiguo 27-05-2004
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 27
__cadetill Va por buen camino
Cita:
Empezado por marto
Copia y pega el código, lo pruebas y luego me cuentas
pues sí, pues sí, funciona, y yo complicándome la vida!!!!
Responder Con Cita
  #6  
Antiguo 27-05-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Estimado Cadetill:

He respasado el código Delphi aunque no estoy muy ducho en la sintaxis de Delphi creo que es exáctamente lo que yo hago. Pero me alegra ver que ya más o menos se sabe por donde van los tiros.

Pego a continuación mi código:
Código:
 
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
 
static inline void ValidCtrCheck(TSRichEdit *)
{
  new TSRichEdit(NULL);
}
//---------------------------------------------------------------------------
__fastcall TSRichEdit::TSRichEdit(TComponent* Owner)
: TRichEdit(Owner)
{
  ExOnSelectionChange=false;
  Primer_evento=false;
} 
//---------------------------------------------------------------------------
namespace Srichedit
{
	void __fastcall PACKAGE Register()
  {
	TComponentClass classes[1] = {__classid(TSRichEdit)};
	RegisterComponents("Samples", classes, 0);
  }
}
//---------------------------------------------------------------------------
void __fastcall TSRichEdit::WndProc (Messages::TMessage &Message)
{
  if (!Primer_evento)
  { 
	{
	   Primer_evento=true;
	   if (OnSelectionChange!=NULL)
	   {
		 ExOnSelectionChange=true;
		 FExOnSelectionChange=OnSelectionChange;
	   }
 
	   OnSelectionChange=FInOnSelectionChange;
	   ShowMessage("Hola quillo 0");
	   OnSelectionChange=FExOnSelectionChange;
	 }
   }
 
  TWinControl::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TSRichEdit::FInOnSelectionChange (TObject *Sender)
{
  ShowMessage("Hola Quillo 1");
  if (ExOnSelectionChange)
  FExOnSelectionChange(Owner);
}
//---------------------------------------------------------------------------
Según entiendo yo, es lo mismo, salvo que el puntero a la funcion FExOnSelectionChange no lo he declarado como una propiedad. El problema sigue siendo el mismo, mientras estoy en modo de diseño de la aplicación. El componente se ejecuta y en la linea en la que se suplanta el MAnejador del evento, se porvoca el borrado de la citada casilla en el Inspector de objetos

Te dejo el código por si puedes darme alguna pista
Gracias

Última edición por marto fecha: 27-05-2004 a las 13:20:58.
Responder Con Cita
  #7  
Antiguo 27-05-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Guau! He ido a desayunar, no me esperaba que respondiérais tan rápido, muchísimas gracias. Respondo a Marto, diciendo que no se me había ocurrido esa forma de implemetar mi función, entre otras cosas porque desconocía el siginificado de Inherit;.

Voy a intentar hacer una traducción a Borland y a ver que pasa, No creo que tarde más de 15 minutos.

Por cierto aun no se si lo que hago es un VCL o un template, por favor si puedes aclararmelo o direccionarme a alguna página te lo agradecería.
Responder Con Cita
  #8  
Antiguo 27-05-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 24
marto Va por buen camino
Cita:
Empezado por Sonic
Por cierto aun no se si lo que hago es un VCL o un template, por favor si puedes aclararmelo o direccionarme a alguna página te lo agradecería.
Bueno... si lo que haces es Component -> Create Component Template, no estás creando un componente nuevo verdaderamente. En realidad estás duplicando una insatancia, es como si copiases y pegases el componente de un form a otro juntamente con los eventos asociados. Cada vez que dejas caer tu template en un form nuevo, todo ese codigo se crea en la unit correspondiente.
Inconvenientes: Si quieres cambiar algo de ese código, vas a tener que hacerlo en todos los sitios donde dejaste el componente. Además, el código está "visible" en todos lados y puede ser modificado involuntariamente. No nos olvidemos del estilo, es mucho más cómodo que el código no se vea y trabajemos de contra una "caja negra".
Para evitar todos esos inconvenientes, se crea un componente nuevo, es decir una nueva clase. Si no me quivoco esto es lo que intentas y tambien a lo que te refieres por "crear un VCL", si no es así corrígeme
Ah! por cierto, por favor encierra tu código entre tags "code"..."/code" para que se vea bien... ¿de verdad crees que muchos se van a poner a intentar un código de tantas líneas que no está siquiera indentado?
__________________
E pur si muove

Última edición por marto fecha: 27-05-2004 a las 13:10:07.
Responder Con Cita
  #9  
Antiguo 27-05-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Vale Marto:

Muchas gracias ya veo la diferencia, y sí, tienes razón es precisamente lo que quiero hacer.

Por lo de mi código, pido perdón os aseguro que está indentado, que yo soy muy ordenado con el código que escribo, pero es la primera vez que pego código en este foro y no se hacer lo de los tags que me dices.

Bueno estoy probando lo del inherited pero no me sale, me da una serie de errores precisamente en esa isntrucción. A mi me gusta investigar un poco por mi cuenta antes de pedir ayuda así que voy a intentarlo un rato más y si no me sale postearé de nuevo.

Otra vez muchas gracias me estais siendo de mucha ayuda!

" asd"
Responder Con Cita
  #10  
Antiguo 27-05-2004
Avatar de marto
marto marto is offline
Miembro
 
Registrado: may 2003
Ubicación: Barcelona, Catalunya
Posts: 882
Poder: 24
marto Va por buen camino
Cita:
Empezado por Sonic
Por lo de mi código, pido perdón os aseguro que está indentado, que yo soy muy ordenado con el código que escribo, pero es la primera vez que pego código en este foro y no se hacer lo de los tags que me dices.
Bueno, por esta vez ya te lo he hecho yo, pulsa tu mismo en "editar" y verás como lo he hecho
__________________
E pur si muove
Responder Con Cita
  #11  
Antiguo 27-05-2004
Sonic Sonic is offline
Miembro
 
Registrado: may 2004
Posts: 40
Poder: 0
Sonic Va por buen camino
Muchas gracias por explicarme cómo pegar código.

Lo siento pero no consigo que el código funcione.
A continuación pego lo que he escrito:

Código:
 
 // ValidCtrCheck is used to assure that the components created do not have
 // any pure virtual functions.
 //
 
 static inline void ValidCtrCheck(TSRichEdit *)
 {
 		new TSRichEdit(NULL);
 }
 //---------------------------------------------------------------------------
 __fastcall TSRichEdit::TSRichEdit(TComponent* Owner)
 		: TRichEdit(Owner)
 {
 }
 //---------------------------------------------------------------------------
 namespace Srichedit
 {
 		void __fastcall PACKAGE Register()
 		{
 				 TComponentClass classes[1] = {__classid(TSRichEdit)};
 				 RegisterComponents("Samples", classes, 0);
 		}
 }
 //---------------------------------------------------------------------------
 void __fastcall TSRichEdit::SelectionChange (TObject *Sender)
 {
   ShowMessage("Hola Quillo 1aaaaa");
   inherited SelectionChange(TObject *Sender);
   //TCustomRichEdit::SelectionChange();  // Esto tampoco funciona
 }
Defino la función SelectionChange y recibo el warning de que estoy tapando a la virtual de TCustomRichEdit.

Pero cuando ejecuto el código y ocurre un evento OnSelectionChange solo se ejecuta el código de usuario y no el interno de mi componente.

Tras ver ese post de pista que ofreciste, se me ocurrio sencillamente suplantar al WndProc y capturar el mensaje EN_SELCHANGE, y tras esto ejecutar mi código y luego llamar al WndProc del TWinControl. Esto último ya lo he hecho con otro tipo de mensajes y funciona pero el mensaje EN_SELCHANGE no consigo capturarlo.

Así que de nuevo estoy estancado. Como puedes ver en el código e intentado usar lo de Inherited y esa parece ser la única forma en que compila y la linea que hay más abajo comentada es (según creo yo) otra forma de hacer lo mismo pero que tampoco funciona.

Ah otra cosa, viendo que no funcionaba miré esto:
Cita:
Empezado por Marto
begin
if Assigned(OnSelectionChange) then OnSelectionChange(Self);
E intenté implantarlo en el constructor de mi objeto de la siguiente manera:
Código:
   if (OnSelectionChange==NULL)
 	 OnSelectrionChange=SelectrionChange;
y también lo intenté con el Self que parece no reconocerlo de ninguna manera.

Tal y como lo veo ahora tengo dos opciones: intentar seguir por el camino que me marcó Marto, o instentar capturar el mensaje EN_SELCHANGE. Cualquiera de las dos soluciones me serviría. Aunque preferiría poder usar la de Marto ya que me parece la más sencilla de las dos (en cuanto a la estructura del programa).

Muchas Gracias
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 21:22:02.


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
Copyright 1996-2007 Club Delphi