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

Résolu
cs_pouicky Messages postés 19 Date d'inscription lundi 26 avril 2004 Statut Membre Dernière intervention 4 août 2010 - 19 déc. 2005 à 22:22
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 - 22 déc. 2005 à 01:23
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?-->)

10 réponses

cs_pouicky Messages postés 19 Date d'inscription lundi 26 avril 2004 Statut Membre Dernière intervention 4 août 2010
21 déc. 2005 à 22:18
ç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



<HR>
rame, rame, rameurs, ramez....
3
Rejoignez-nous