Utilisation de FindComponent dans une unité [Résolu]

dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 30 janv. 2018 à 18:22 - Dernière réponse : dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention
- 6 févr. 2018 à 12:41
Bonjour,
J'essaie de faire une unité avec des fonctions et procédures qui fonctionnent parfaitement lorsqu'elles sont intégrées à une application, mais produisent une erreur si je les passe en unités.
Voici le code :
unit uCreaPanel;

//############################//
         INTERFACE
//############################//   

uses SysUtils,
     StrUtils,
     Classes,
     controls,
     graphics,
     extctrls
     ;

    /// ========================= BMulti Panels  ===============================
    procedure CreaPAN(NL,NC:integer; L,H:integer; X,Y:integer; c:Tcolor;
                      KNOM:string; papa:TWincontrol; PROC:TNotifyEvent);
    procedure FreePAN(NL,NC:integer; KNOM:string);
    procedure TextePAN(n:integer; T:string; KNOM:string);
    procedure ColorPAN(n:integer; C:Tcolor; KNOM:string);
    //procedure ClicBP(Sender: TObject);


//############################//
         IMPLEMENTATION
//############################//



//##############################################################################
///*****************************************************************************
///*************************** MULTIPANEL **************************************
///*****************************************************************************
//##############################################################################

//--------------------------------------------------
procedure CreaPAN(NL,NC:integer; L,H:integer; X,Y:integer; c:Tcolor;
                 KNOM:string; papa:TWincontrol; PROC:TNotifyEvent);
var i,j,xx:Integer; z:string; bb:TPanel;
// panels créés : PAN1 à PANx  avec x = NC*NL      
begin
for j:=0 to NL-1 do
    for i:=0 to NC-1 do
        begin
        xx := j*nC+i+1;
        z := KNOM + IntToStr(xx);
        bb := TPanel.Create(papa);
        bb.Name    := z;
        bb.Left    := i*L+X;
        bb.top     := j*H+Y;
        bb.width   := L;
        bb.height  := H;
        bb.Color   := c;
        bb.BevelWidth := 1;
        bb.caption := '';
        bb.Parent  := papa;
        bb.visible := true;
        bb.Tag     := xx;
        bb.Caption := inttostr(xx);
        bb.BringToFront;
        bb.OnClick := PROC;
        end
end;

//----------------------------------------------------
procedure FreePAN(NL,NC:integer; KNOM:string);
var i:integer;
begin
for i:=0 to NL*NC-1 do Tpanel(findComponent(KNOM + inttostr(i))).Free
end;
//----------------------------------------------------
procedure TextePAN(n:integer; T:string; KNOM:string);
begin
Tpanel(tpanel.findComponent(KNOM + inttostr(n))).Caption := T
end;

//----------------------------------------------------
procedure ColorPAN(n:integer; C:Tcolor; KNOM:string);
begin
Tpanel(findComponent(KNOM + inttostr(n))).Color := C
end;


END;


Erreur à la compilation : "identificateur non déclaré : findComponent"
FindComponent appartient à priori à Tcomponent contenu lui même dans "Classes"
Bref je sêche !
merci
Afficher la suite 

11 réponses

Répondre au sujet
korgis 401 Messages postés samedi 17 mai 2003Date d'inscription 1 février 2018 Dernière intervention - 30 janv. 2018 à 19:28
0
Utile
6
Salut,

sans trop rentrer dans le détail, pour la procedure FreePan, par exemple, je ferais :

procedure FreePAN(NL, NC: integer; KNOM: string; papa: TWincontrol);
var
  i: integer;
begin
  for i := 0 to NL * NC - 1 do
    with papa do
      Tpanel(FindComponent(KNOM + IntToStr(i))).Free;
end;


Faut pas oublier le "papa"...
dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 31 janv. 2018 à 08:28
ça marche impec, mais cela me crée une erreur justement dans le fameux module panel cité précédemment
Peut être soumettrai-je ce pb plus tard !!
Merci, l'unité fonctionne
korgis 401 Messages postés samedi 17 mai 2003Date d'inscription 1 février 2018 Dernière intervention - 1 févr. 2018 à 15:40
Hello,

En y réfléchissant, la manière dont tu nommes le paramète "papa" (TWincontrol) au moment de la création des panels me semble pouvoir être trompeur.
Car attention de ne pas confondre "Owner" et "Parent".
Le Owner possède tous les composants qui lui appartiennent (et les détruit au moment de sa destruction).
Le parent, lui, affiche ses contrôles enfants.
Le Owner n'est pas forcément parent, et vice-versa.
Pour approfondir le sujet, voir "TWinControl.Controls", "TComponent.Components", "TWinControl.FindChildControl", "TComponent.FindComponent" etc... dans l'aide en ligne de Delphi.

(Un papa. Une maman. On ne ment pas aux enfants ^^)
dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 2 févr. 2018 à 08:17
Oui Korgis tu as diablement raison !
J'ai un autre module qui transforme les panels en Button et dans le cas des panels déposés sur la fiche il m'a fallu enlever le papa et le mettre par contre dans le cas d'un panel créé dynamiquement.
Pour info voici le module en question :
{##############################################################################}
{#============================================================================#}
{#============================= Module MouseBP ===============================#}
{#============================================================================#}
{#} {#}
{#============================================================================#}
{#} {#}
{#} //---------------------------------------------------------- MouseBP {#}
{#} procedure TForm1.MouseBP(Sender: TObject; Button: TMouseButton; {#}
{#} Shift: TShiftState; X, Y: Integer); {#}
{#} var {#}
{#} C1, C2: TColor; {#}
{#} begin {#}
{#} with Sender as TPanel do {#}
{#} begin {#}
{#} // Echange de couleur Fond/Texte pendant le clic // Merci Korgis {#}
{#} C1 := Color; {#}
{#} C2 := Font.color; {#}
{#} Color := C2; {#}
{#} Font.Color := C1; {#}
{#} if BevelOuter = bvRaised {#}
{#} then BevelOuter := bvLowered {#}
{#} else BevelOuter := bvRaised; {#}
{#} end; {#}
{#} end; {#}
{#} {#}
{#} // à utiliser pour les panels déposés sur la forme {#}
{#} //------------------------------------------------------ InitPanelBP {#}
{#} procedure TForm1.InitPanelBP(n: integer; z: string; mode: boolean); {#}
{#} var i:integer; // W:string; {#}
{#} begin {#}
{#} for i:= 1 to n do setPanelBP(z,i,mode); {#}
{#} end; {#}
{#} //------------------------------------------------------ SetPanelBP {#}
{#} procedure TForm1.SetPanelBP(z: string; n: integer; mode: boolean); {#}
{#} var W:string; {#}
{#} begin {#}
{#} W := z + inttostr(n); // name du panel concerné {#}
{#} if mode then Tpanel(findComponent(W)).BevelInner := BvSpace; {#}
{#} if mode then Tpanel(findComponent(W)).BevelOuter := bvRaised; {#}
{#} if mode then Tpanel(findComponent(W)).BevelWidth := 2; {#}
{#} if mode then Tpanel(findComponent(W)).BorderWidth := 0; {#}
{#} Tpanel(findComponent(W)).OnMouseUp := MouseBP; {#}
{#} Tpanel(findComponent(W)).OnMouseDown := MouseBP; {#}
{#} end; {#}
{#} {#}
{#} // à utiliser pour les panels créés dynamiquement avec CreaPAN {#}
{#} //------------------------------------------------------ InitMouseBP {#}
{#} procedure TForm1.InitMouseBP(n:integer; {#}
{#} z:string; {#}
{#} papa:TWincontrol; {#}
{#} mode:boolean=false); {#}
{#} var i:integer; {#}
{#} begin {#}
{#} for i:= 1 to n do setMouseBP(z,i,papa,mode); {#}
{#} end; {#}
{#} //------------------------------------------------------ SetMouseBP {#}
{#} procedure TForm1.SetMouseBP(z:string; {#}
{#} n:integer; {#}
{#} papa:TWincontrol; {#}
{#} mode:boolean=false); {#}
{#} var W:string; {#}
{#} begin {#}
{#} W := z + inttostr(n); // name du panel concerné {#}
{#} if mode then Tpanel(papa.findComponent(W)).BevelInner := BvSpace; {#}
{#} if mode then Tpanel(papa.findComponent(W)).BevelOuter := bvRaised; {#}
{#} if mode then Tpanel(papa.findComponent(W)).BevelWidth := 2; {#}
{#} if mode then Tpanel(papa.findComponent(W)).BorderWidth := 0; {#}
{#} Tpanel(papa.findComponent(W)).OnMouseUp := MouseBP; {#}
{#} Tpanel(papa.findComponent(W)).OnMouseDown := MouseBP; {#}
{#} end; {#}
{#} {#}
{##############################################################################}
papyvore 146 Messages postés samedi 15 novembre 2003Date d'inscription 4 février 2018 Dernière intervention - 4 févr. 2018 à 13:33
bonjour
as tu essayé avec 1 tframe

unit uFrame;

interface

uses
System.SysUtils, System.Classes, Vcl.ExtCtrls, Vcl.Controls, Vcl.Forms,
Vcl.Graphics;

type
TFrame1 = class(TFrame)
private

{ Déclarations privées }
public
{ Déclarations publiques }
procedure CreaPAN(NL, NC: integer; L, H: integer; X, Y: integer; c: Tcolor;
KNOM: string; papa: TWincontrol; PROC: TNotifyEvent);
procedure FreePAN(NL, NC: integer; papa: TWincontrol);
procedure TextePAN(n: integer; T: string; KNOM: string; papa: TWincontrol);
procedure ColorPAN(n: integer; c: Tcolor; KNOM: string; papa: TWincontrol);

constructor Create(AOwner: TComponent); override;
end;

implementation

{$R *.dfm}

Constructor TFrame1.Create(AOwner: TComponent);
begin
inherited;
end;

procedure TFrame1.CreaPAN(NL, NC: integer; L, H: integer; X, Y: integer;
c: Tcolor; KNOM: string; papa: TWincontrol; PROC: TNotifyEvent);
var
i, j, xx: integer;
z: string;
bb: TPanel;
// panels créés : PAN1 à PANx avec x = NC*NL
begin
for j := 0 to NL - 1 do
for i := 0 to NC - 1 do
begin
xx := j * NC + i + 1;
z := KNOM + IntToStr(xx);
bb := TPanel.Create(papa);
bb.Name := z;
bb.Left := i * L + X;
bb.top := j * H + Y;
bb.width := L;
bb.height := H;
bb.Color := c;
bb.BevelWidth := 1;
bb.caption := '';
bb.Parent := papa;
bb.visible := true;
bb.Tag := xx;
bb.caption := IntToStr(xx);
bb.BringToFront;
bb.OnClick := PROC;
end
end;

// ----------------------------------------------------
procedure TFrame1.FreePAN(NL, NC: integer; papa: TWincontrol);
var
i : integer;
begin { ne marche pas ???
for i := 0 to (NL * NC) - 1 do
begin
If papa.Components[i] Is TPanel Then
TPanel(papa.Components[i]).Destroy; // Free;
end;
}
end;

// ----------------------------------------------------
procedure TFrame1.TextePAN(n: integer; T: string; KNOM: string;
papa: TWincontrol);
var
i: integer;
begin
For i := 0 To papa.ComponentCount - 1 Do
If papa.Components[i] Is TPanel Then
if TPanel(papa.Components[i]).Name = KNOM + IntToStr(n) then
begin
TPanel(papa.Components[i]).caption := T;
end;
end;

// ----------------------------------------------------
procedure TFrame1.ColorPAN(n: integer; c: Tcolor; KNOM: string;
papa: TWincontrol);
var
i: integer;
begin
For i := 0 To papa.ComponentCount - 1 Do
If papa.Components[i] Is TPanel Then
if TPanel(papa.Components[i]).Name = KNOM + IntToStr(n) then
begin
TPanel(papa.Components[i]).ParentColor := false;
TPanel(papa.Components[i]).ParentBackground := false;
TPanel(papa.Components[i]).Color := c;
end;

end;

end.

et un appel

FActiveFrame := TFrame1.Create(Self);
FActiveFrame.Name := '';
FActiveFrame.Parent := Self;

NL := 2;
NC := 4;
L := 120;
H := 200;
X := 40;
Y := 10;
KNOM := 'KNOM';
c := clRed;

FActiveFrame.CreaPAN(NL, NC, L, H, X, Y, c, KNOM, Form7, PROC);

FActiveFrame.TextePAN(3, 'azerty', KNOM, Form7 );
FActiveFrame.TextePAN(1, 'TOTO', KNOM, Form7 );

FActiveFrame.ColorPAN(3, clBlue, KNOM, Form7 );
FActiveFrame.ColorPAN(4, clRed, KNOM, Form7 );

j'ai testé ça marche mais c'est peut être pas exactement ce que tu cherche
Salut,
pourquoi ne pas prendre le problème autrement et se passer de papa, maman etc...et mettre une option click sur tous les TPanel...
unit UnitPanel;

interface

uses
  Messages, Classes, Graphics, Controls, ExtCtrls;

type
  TPanel = class(ExtCtrls.TPanel)
  private
    FOptionClick : Boolean;
    FColorLowered : TColor;
    FColorRaised : TColor;
    procedure SetOptionClick(Value: Boolean);
    procedure SetColorLowered(Value: TColor);
    procedure SetColorRaised(Value: TColor);
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
  public
    constructor Create(AOwner : TComponent); override;
    property OptionClick : Boolean read FOptionClick write SetOptionClick;
    property ColorLowered : TColor read FColorLowered write SetColorLowered;
    property ColorRaised : TColor read FColorRaised write SetColorRaised;
  end;

implementation

constructor TPanel.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  OptionClick := True;
  ColorLowered := Color;
  ColorRaised := Font.Color;
end;

procedure TPanel.SetColorLowered(Value: TColor);
begin
  if Value <> FColorLowered then
  begin
    FColorLowered := Value;
    Invalidate;
  end;
end;

procedure TPanel.SetColorRaised(Value: TColor);
begin
  if Value <> FColorRaised then
  begin
    FColorRaised := Value;
    Invalidate;
  end;
end;

procedure TPanel.SetOptionClick(Value: Boolean);
begin
  if Value <> FOptionClick then
  begin
    FOptionClick := Value;
    Invalidate;
  end;
end;

procedure TPanel.WMLButtonUp(var Message: TWMLButtonUp);
begin
  if OptionClick then
  begin
    Font.Color := ColorRaised;
    BevelOuter := bvRaised;
  end;
  inherited;
end;

procedure TPanel.WMLButtonDown(var Message: TWMLButtonDown);
begin
  if OptionClick then
  begin
    Font.Color := ColorLowered;
    BevelOuter := bvLowered;
  end;
  inherited;
end;

end.

Pour l'exemple dans une Form mettre 2 panel et 1 bouton créer l'unité UnitPanel et la mettre dans les uses...
Si on clique sur bouton on enlève et remet l'option du click sur le panel 1.
Et on peut si on veut gérer les couleurs de font par ColorLowered et ColorRaised.
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, UnitPanel;

type

  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Panel1.OptionClick := not Panel1.OptionClick;
end;
@+
Commenter la réponse de korgis
dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 5 févr. 2018 à 17:39
0
Utile
3
Salut Yanb, Salut Papyvore
Je n'ai encore testé que la version de Yannb : ça marche bien : tous les panels déposés sur la fiche deviennent des boutons ; par contre cela ne touche pas les panel créés dynamiquement par mon creaPanel.
Pour l'instant avec mon système je peux transformer une série de panels bien définis (ex: panels XXX1 à nXXX17) les autres panels restant de vrai panels.

Pour le frame, la mise en place semble être plus complexe à mettre en oeuvre rapidement sur une appli standard

Merci à tous les deux, j'ai de quoi passer les longues journées d'hiver qui restent !
dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 5 févr. 2018 à 17:46
Rectification : c'est la version de YanB : UnitPanel que j'ai testée et non celle de papyvore (inversion des noms dans le commentaire précédent)
(désolé, c'est surement l'age !!!)
Salut,
Oui normal que ça ne fonctionne pas avec tes panel créaient dynamiquement, car je l'ai mis pour l'exemple dans l'unité principal mais si tu met UnitPanel dans les uses de ton uCreaPanel ceci devrait se passer autrement ;)
@+
dubois77 685 Messages postés jeudi 17 avril 2008Date d'inscription 6 février 2018 Dernière intervention - 6 févr. 2018 à 12:41
Je viens d'essayer, avec le UnitPanel seulement dans l'unit Creapanel, seuls les dynamiques fonctionnent,
Mais le unitPanel dans l'unit ET dans l'appli : çà marche nickel
Merci YanB
Commenter la réponse de dubois77

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.