begin process at 2010 02 10 01:57:00
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive Delphi

 > 

Archives

 > 

Graphique

 > 

Entrer dans l'évenement Onchange dans un sous-composant


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Entrer dans l'évenement Onchange dans un sous-composant

lundi 19 décembre 2005 à 22:22:35 | Entrer dans l'évenement Onchange dans un sous-composant

pouicky

j'ai un probleme d'entrée dans l'evenement onChange d'un TEdit instancié
par un TPersoDBGrid, l'ensemble devant devenir un composant unique. Voici la source édulcorée et commentée:

//Déclarations dans la même unité des deux osus-composants:
interface

uses
  SysUtils, Classes, StdCtrls, Controls, Grids,
  DBGrids,Types,ADODB,Graphics,DB,Messages;

var
  nomDeChamp:string;
  DataSet: TDataSet;
  //Le TDataset doit servir à la fois pour le TPersoEDIT et le TPersoDBGRID
  //il est initialisé dans la méthode selectTitre() du TPersoDBGRid;
 
type //composant TEDIT

//Derivé de TEDIT: sous-classe créée pour gérer les évenements
 TPersoEdit=class(TEdit)
    protected
     procedure WMMouseWheel(var Msg: TWMMOUSEWHEEL); message WM_MOUSEWHEEL;//sert à rendre le focus à la DBGrid et fonctionne.
        procedure Change(); override;
       
    end;
//-------------------------------------------------------------

//Derivé de TDBGrid, base du composant et parent du TPersoEdit
   TPersoDBGrid = class(TDBGrid)
   private
    { Déclarations privées }
     eRecherche:TPersoEdit; 
     procedure selectTitre(Column: TColumn);
     procedure triColonne(Column:TColumn);

    protected //visible pour les seuls descendants de la TPersoDBGrid
 { Déclarations protégées }
    procedure CellClick(Column: TColumn);override;//et pas overload car la methode surchargée est virtuelle
  procedure TitleClick(Column:TColumn);override;
     procedure DrawColumnCell(const Rect:TRect;DataCol:Integer;Column:TColumn;State:TGridDrawState);override;
     procedure WMMouseWheel(var Msg: TWMMOUSEWHEEL); message WM_MOUSEWHEEL;

    public //visible pour toutes les classes
//popMenuPerso:TPopupMenu; //à programmer
     constructor Create(Owner:TComponent);override;
     destructor Destroy();override;

    published
  //...non recopié
 end;
//-------------------------------------------------------------


//Les procédure et méthodes en jeu à mon sens:
constructor TPersoDBGrid.Create(Owner:TComponent);
begin
 eRecherche:=TPersoEdit.Create(Self);//chaque ligne est parcourue au debogage
    with eRecherche do
    begin
     Parent:=self;
     Ctl3D:=False;
     Text:='';
     Visible:=false;
    end;
end;
//apres cette ligne, le débogueur on passe à "application.run" du projet
//ensuite on entre dans TPersoEdit.Change pour la premiere et derniere fois
   
procedure TPersoDBGrid.TitleClick(Column:TColumn);
begin
 //execution des fonctions attachées au tri
 selectTitre(Column);//voir fonctions en bas de page
    eRecherche.Visible:=True;
    eRecherche.SetFocus;
    triColonne(Column); //voir fonctions en bas de page
 //execution de l'évènement du développeur si il est assigné
 if Assigned(onTitleCLick) then onTitleclick(Column);
end;  
   
procedure TPersoDBGrid.DrawColumnCell(const Rect:TRect;DataCol:Integer;Column:TColumn;State:TGridDrawState);
begin
 //si l'etat "selectionné" est trouvé dans le TGridDrawState pour une cellule
   If gdSelected In State Then
    Begin
//...récupération des dimensions de largeur pour tailler le TPersoEdit non recopié
//...colorisation des cellules non recopié
       selectTitre(Column);
   //select titre effectue la colorisation de l'entête,
   //récupére le champ actif, et
   //initialise le dataset utilsé aussi dans le TPersoEdit.onChange.
   End;
//...autres opérations de coloriages non recopiées
   DefaultDrawColumnCell(rect,datacol,column,state);
end;

//la methode selectTitre où est initialisé le TDATASET
procedure TPersoDBGrid.selectTitre(Column: TColumn);
var i:integer;
begin
//...adaptation du TEdit nommé eRecherche à la colonne (non recopié)
    //affectation du champ courant dans sa variable globale
    nomDeChamp:=Column.FieldName;
//gestion de l'index de selection
     SelectedIndex:=Column.Index;
//...Gestion des couleurs des titres non recopiée
end;

//!!!!!C'est ici que le code n'est pas parcouru, sauf à l'instanciation du composant.(vu avec f8 et point d'arret)!!!!
procedure TPersoEdit.Change;
begin 
    if DataSet=nil then exit;
    inherited Change;
 DataSet.Locate(nomDeChamp,Text,[loCaseInsensitive,loPartialKey]);
end;

//...procedure register non recopiée

J'ai une piste sans idée de solution :
serait-ce la fiche qui emet le message onchange au TEdit et pas son parent TPersoDBGrid? comment gérer cela (intercepter les messages keyPress?-->)

lundi 19 décembre 2005 à 22:28:55 | Re : Entrer dans l'évenement Onchange dans un sous-composant

pouicky

Autre question : peut-on insérer des sources delphi avec la colorisation dans les forums?
mardi 20 décembre 2005 à 12:13:06 | Re : Entrer dans l'évenement Onchange dans un sous-composant

cirec

Membre Club Administrateur CodeS-SourceS
Salut,
Regarde ceci, j'ai fait un petit essai de code avec un evenement onChange déclarer dans le OnCreate de la Form ( pour toi il faudrat le mettre dans le constructor TPersoDBGrid.Create(Owner:TComponent)) ce qui est le plus important pour toi je l'ai mis en rouge.

l'exemple suivant modifie le label1 quand le texte de l'Edit1 est modifier

type
TForm1 = class(TForm)
Label1: TLabel
;
Edit1: TEdit
;
procedure
FormCreate(Sender: TObject);
procedure
EditChanged (Sender: TObject);
private
{ Déclarations privées }
public
{ Déclarations publiques }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure
TForm1.FormCreate(Sender: TObject);
begin
TEdit(Edit1).OnChange := EditChanged;
end
;

procedure
TForm1.EditChanged(Sender: TObject);
begin
Label1.Caption := Edit1.Text;
end
;

end
.

Voilà donc ce qu'il fait faire dans ton cas pour que ça fonctionne :

//Derivé de TDBGrid, base du composant et parent du TPersoEdit
  TPersoDBGrid = class(TDBGrid)
  private
    { Déclarations privées }
     eRecherche:TPersoEdit; 
     procedure EditChanged(Sender : TObject); //à déclarer comme ceci
     procedure selectTitre(Column: TColumn);
     procedure triColonne(Column:TColumn);
  protected //visible pour les seuls descendants de la TPersoDBGrid
 { Déclarations protégées }
   ...
   ...
   ...
  public //visible pour toutes les classes
//popMenuPerso:TPopupMenu; //à programmer
     constructor Create(Owner:TComponent);override;
     destructor Destroy();override;

    published
  //...non recopié
 end;
//-------------------------------------------------------------
//Les procédure et méthodes en jeu à mon sens:
constructor TPersoDBGrid.Create(Owner:TComponent);
begin
 eRecherche:=TPersoEdit.Create(Self);//chaque ligne est parcourue au debogage
    with eRecherche do
    begin
     Parent:=self;
     Ctl3D:=False;
     Text:='';
     Visible:=false;
    end;
TEdit(eRecherche).OnChange := EditChanged;// ici onl'affecte à eRecherche(Edit)
end;

//et la procedure en elle même tu remarqueras que tout est déclarer sous TPersoDBGrid
procedure
TPersoDBGrid.EditChanged(Sender: TObject);
begin
    if DataSet=nil then exit;
    inherited Change;
 DataSet.Locate(nomDeChamp,Text,[loCaseInsensitive,loPartialKey]);
end;


ceci fonctionne avec certitude, je l'utilise asser souvant pour redéfinir le onChange d'un composant.
 
En ce qui concerne la deuxièmme question tu peux soit le faire manellement (ce que je fait si il n'y a que quelques lignes) où si c'est plus long il existe un editeur de code qui est libre qui s'appel ConTEXT et tu peux le trouver à www.context.cx  et celui ci est très pratique (à mon avis) puisque tu peux éditer ton code (supporte plusieurs langages) et en suite directement le mettre dans le presse-papier au format rtf et ensuite il ne reste plus qu'à faire coller.
Bon c'est ma methode il y a peut être plus simple mais bon cette éditeur vaut bien un coup d'oeil (il est bien sur possible de le mettre en français)



@+


mercredi 21 décembre 2005 à 01:33:10 | Re : Entrer dans l'évenement Onchange dans un sous-composant

pouicky

J'ai l'impression que mon probleme releve de la gestion des évènements windows,, theme abordé au lien suivant que je potasserai moins fatigué (il se fait tard, finalement)

[ Lien ]

Cet article qui se veut "de base" mais est excellent et me semble tres pointu pour ce qui nos interesse là.

Si quelqu'un a une astuce simple je suis toujours preneur. ;)

mercredi 21 décembre 2005 à 01:36:47 | Re : Entrer dans l'évenement Onchange dans un sous-composant

cirec

Membre Club Administrateur CodeS-SourceS
ce que je t'ai mis fonctionne essaye le

@+
Cirec
mercredi 21 décembre 2005 à 01:59:39 | Re : Entrer dans l'évenement Onchange dans un sous-composant

pouicky

oups, Le post précédent n'est pas passé.
 Mêmes symptômes qu'avant: un seul passage dans EditChanged au lancement de l'application test de ce composant. Voici l'essentiel du test...en couleurs ;)

type

// sous-classe créée pour modifier le comportement du tedit

TPersoEdit=class(TEdit)

private

protected

procedure WMMouseWheel(var Msg: TWMMOUSEWHEEL);message WM_MOUSEWHEEL;

public

published

end;

TPersoDBGrid =class(TDBGrid)

private//visible pour la seule TPersoDBGrid

{ Déclarations privées }

eRecherche:TPersoEdit;

procedure EditChanged(Sender:TObject);//déclaré sous PersoDBGrId

procedure selectTitre(Column: TColumn);

procedure triColonne(Column:TColumn);

protected//visible pour les seuls descendants de la TPersoDBGrid

{ Déclarations protégées }

procedure CellClick(Column: TColumn);override;//et pas overload car la methode surchargée est virtuelle

procedure TitleClick(Column:TColumn);override;

procedure DrawColumnCell(const Rect:TRect;DataCol:Integer;Column:TColumn;State:TGridDrawState);override;

//WMMouseWheel réagira aux messages de type roulette

procedure WMMouseWheel(var Msg: TWMMOUSEWHEEL);message WM_MOUSEWHEEL;

public//visible pour toutes les classes

constructor Create(Owner:TComponent);override;

destructor Destroy();override;

published//comme public mais visible en plus à la conception graphique

property ...

end;

procedureRegister;

implementation

var

nomDeChamp:string;

DataSet: TDataSet;

leftCellule,rightCellule:Integer;

constructor TPersoDBGrid.Create(Owner:TComponent);

begin

inherited Create(Owner);//Constructeur herité

//colorisations par défaut

//Instanciation d'une zone de saisie

eRecherche:=TPersoEdit.Create(Self);

with eRecherche do

begin

Parent:=self;

Ctl3D:=False;

Text:='';

Visible:=false;

end;

TEdit(eRecherche).OnChange:=EditChanged;

end;

destructor TpersoDBGrid.Destroy;

begin

eRecherche.Free;

Dataset.Free;

inherited Destroy;

end;

procedure TPersoDBGrid.TitleClick(Column:TColumn);

begin

//execution des fonctions attachées au tri

selectTitre(Column);//voir fonctions en bas de page

eRecherche.Visible:=True;

eRecherche.SetFocus;

triColonne(Column);//voir fonctions en bas de page

//execution de l'évènement du développeur si il est assigné

if Assigned(onTitleCLick)then onTitleclick(Column);

end;

procedure TPersoDBGrid.CellClick(Column: TColumn);

begin

with eRecherche do

begin

Text:='';

visible:=False;

Parent.SetFocus;

end;

end;

procedure TPersoDBGrid.DrawColumnCell(const Rect:TRect;DataCol:Integer;Column:TColumn;State:TGridDrawState);

begin

//si l'etat "selectionné" est trouvé dans le TGridDrawState pour une cellule

If gdSelected In State Then

Begin

//récupérer la position de la cellule selectionnée

leftCellule:=rect.Left;

rightCellule:=rect.Right;

//coloriser si les cellules concernées

//lancer la fonction de colorisation de l'entête et récupération du champ actif:

selectTitre(Column);

End

Else//pour les cellules non sélectionnées

Begin

//cas des lignes à index pairs et impairs :coloriages

End;

//appliquer l'operation de redessin

DefaultDrawColumnCell(rect,datacol,column,state);

end;

//gestion de la molettesur la grille si elle a le focus

procedure TPersoDBGrid.WMMouseWheel(var Msg: TWMMOUSEWHEEL);

begin

//...
end
;

Exit;

end;

procedure TPersoEdit.WMMouseWheel(var Msg: TWMMOUSEWHEEL);

begin

self.Parent.SetFocus;

end;

procedure TPersoDBGrid.EditChanged(Sender:TObject);//déclaré sous PersoDBGrid

begin

if DataSet=nil then exit;

DataSet.Locate(nomDeChamp,eRecherche.Text,[loCaseInsensitive,loPartialKey]);

end;

procedure TPersoDBGrid.triColonne(Column:TColumn);

begin

//...
end
;

procedure TPersoDBGrid.selectTitre(Column: TColumn);

var i:integer;

begin

//adaptation du TEdit nommé eRecherche à la colonne

with eRecherche do

begin

Left:=leftCellule;

width:=rightCellule-leftCellule;

Top:=0;

height:=-Column.Title.Font.Height;

Text:=Column.Title.Caption;

SelStart:=0;

SelLength:=30;

end;

nomDeChamp:=Column.FieldName;

//gestion de l'index de selection

//Gestion des couleurs des titres

end;

procedureRegister;

begin

RegisterComponents('Personnels',[TPersoDBGrid]);

end;

end.




rame, rame, rameurs, ramez....
mercredi 21 décembre 2005 à 02:34:22 | Re : Entrer dans l'évenement Onchange dans un sous-composant

cirec

Membre Club Administrateur CodeS-SourceS
pouicky,
regarde tes messages privés

mercredi 21 décembre 2005 à 19:36:26 | Re : Entrer dans l'évenement Onchange dans un sous-composant

cirec

Membre Club Administrateur CodeS-SourceS

ça y est
à la place de : 
with eRecherche
do
begin
Parent:=self;
Ctl3D:=False;
Text:='';
Visible:=false;
end;
TEdit(eRecherche).OnChange:=EditChanged;
end;


Tu mets ceci :
TPersoEdit=class(TEdit)
private
procedure EditChanged(Sender:TObject); // à déclaré sous PersoEdit en private
protected


with eRecherche do
begin
Parent:=self;
Ctl3D:=False;
Text:='';
OnExit := EditChanged;
Visible:=True;
end;

Et là ça fonctionne très bien tu tapes un texte et quand tu quitte le PersoEdit là il le prend à chaque fois. Alors pourquoi ça ne fonctionne pas avec on change je ne sais pas ? Toujours est-il que j'ai fait des testes avec juste un TPersoEdit et là ça fonctionne tout le temps et dès que je l'intègre à ton Composant ça ne fonctionne plus ?????

Après je me demande si l'utilisation de OnChange était judicieuse puisqu'il aurait déclanché l'évènement à chaque fois qu'une touche était pressée ?



@+
Cirec
mercredi 21 décembre 2005 à 21:42:59 | Re : Entrer dans l'évenement Onchange dans un sous-composant

pouicky


Merci de ton aide et de cette nouvelle info qui me conforte dans ce que je pense:

Je crois que les messages windows atteignent directement l'évenement onChange d'un composant via la fiche qui le contient. Et là, c'est PersoDBGrid le composant qui reçoit les messages windows il ne doit pas faire le relai par sa nature (c'est sûrement de l'à peu pres, mais je vais faire quelques tests en changeant le parent de TPERSOEDIT pour voir).

Merci pour ce test eclaircissant même si je souhaite volontairement faire la recherche dans le champ à chaque touche clavier dans la zone de texte. (d'où l'utilisation des fonctionnalités ado de tri et de recherche sans requete sql supplementaire).
mercredi 21 décembre 2005 à 22:18:44 | Re : Entrer dans l'évenement Onchange dans un sous-composant

pouicky

Réponse acceptée !
ça y est j'ai trouvé
c'était bien ça, l'histoire du message qui n'était pas transmis du PersoDBGrid au TPersoEdit.

ça marche (mais c'est à épurer sûrement) en faisant ceci:
je defini une methode de message sur le message WMChar dans le TEDit
procedure WMChar (var Msg:TWMCHAR);message WM_CHAR;
je défini une methode de message sur le message WMChar dans le DBGrid.
 procedure WMChar (var Msg:TWMCHAR);message WM_CHAR;
la mehode TCBgrid.WMChar a pour fonction d'appeler celle du Tedit en lui passant son parmetre Msg:
procedure TPersoDBGrid.WMChar(var Msg: TWMChar);
begin
  eRecherche.WMChar(Msg);
end;

Et sur la methode TEditWMChar j'effectue le traitement
procedure TPersoEdit.WMChar(var Msg: TWMChar);
begin
  if Msg.CharCode = ord(#13) then //execution sur la touche return
    Begin
    if DataSet=nil then exit;
     //il faudra gérer le type de données ou convertir en string??
  DataSet.Locate(nomDeChamp,Text,[loCaseInsensitive,loPartialKey]);
    end
  else
    inherited;
end;

Je suis assez content de mon intuition à vrai dire




rame, rame, rameurs, ramez....

1 2

Cette discussion est classée dans : end, column, procedure, tpersodbgrid, tpersoedit


Répondre à ce message

Sujets en rapport avec ce message

stingGrid et dbgrid [ par zerargui ] j'ai pris le programme de delphiprog qui est dessousmais à la place d'une base de données Dbase(.dbf) j'ai utilisé une base paradox(.db)alors le progr Dbgrid et index [ par zerargui ] j'ai pris un petit programme de Delphiprog en le modifiant par la lecture des indexes de DBase .DBF par indexex de base Paradox  .db tous s'affiche no thread & dll -> Exception [ par WSTBoss ] Bonjour à tous,j'ai une dll qui contient un thread, tout ce passe bien le thread marche comme il faut mais cependant lors du dechargement de la dll pa Je ne vois pas le probleme de mon code =\ [ par emirej ] Bonjour, en faite j'ai un problème quand je veux compiler mon programme, il me dise qu'il y a une erreur =\Voici mon codeinterfaceuses  Windows, Messa Classe TThread dans composant, liaison entre deux instances ? [ par Bacterius ] Bonjour ! Alors voilà un problème - j'essaye de faire un timer très précis : malheureusement celui-ci a besoin d'un thread pour fonctionner ! Je cherc Rajouter un TreeNode dans un TreeView [ par Francky23012301 ] Salut à tous,Je suis entrain de réaliser un composant dont voici le code :unit BrowserEffects;interfaceuses  Windows, Messages, SysUtils, Classes, Con Création objet, [ par xpmich ] Bonjour,J'ais un petit souci lors de la création d'un objet.voici mon code de l'Unit2 :/************************************************************** Connexion à une base de donnée MySQL [ par kopierreko ] Bonjour tout le monde :)Voilà, je programme en delphi depuis quelques temps et aujourd'hui j'essaie la relation delphi MySQL ...Problème: La connexio Composant en avant plan [ par RURUInc ] Bonjour à tous. J'ai un petit soucis lors du déplacement d'un composant à l'aide de la souris.Je m'expliqueImaginons que j'ai 5 panels sur une form Comment forcer une image à se redessiner ? [ par racimo1985 ] Bonjour tt le monde, j besoin d'un algorithme qui force une image ( deux rectangles en formant un L) à se redessiner lorsqu'on répète l'exécution de l


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,811 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales