Passage par variable .. [Résolu]

jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 1 févr. 2011 à 11:39 - Dernière réponse : cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention
- 11 févr. 2011 à 14:36
Bonjour,

J'ai créé une fonction qui me permet d'encadrer un objet quelconque d'une form
CanvasDest est le canvas de la form contenant l'objet (Label, Edit, Image, RichEdit ...).
Le but étant de "souligner" l'objet ayant le focus par un cadre de couleur

procedure TMainForm.Cadre(EpaisseurCadre : integer; Object_avec_Cadre : Boolean; ObjetRect : TRect; CanvasDest : TCanvas);
var
  X1, X2, Y1 ,Y2, Decalage : integer;
begin
  if Object_avec_Cadre then
    Decalage :=0
  else
    Decalage := 2;


  X1 := ObjetRect.Left - 2 - Trunc((EpaisseurCadre + 1)/2) + Decalage;
  Y1 := ObjetRect.Top  - 2 - Trunc((EpaisseurCadre + 1)/2) + Decalage;

  X2 := ObjetRect.Right - 1 + Trunc((EpaisseurCadre )/2) + Decalage ;
  Y2 := ObjetRect.Bottom - 1  + Trunc((EpaisseurCadre )/2) + Decalage;

  CanvasDest.Pen.Color := ClGreen;
  CanvasDest.Pen.Width := EpaisseurCadre;
  CanvasDest.Brush.Style := bsClear;
  CanvasDest.Rectangle(X1,Y1,X2,Y2);
end;




Cette procedure fonctionne, je l'ai écrite en placant l'appel dans l'événement Paint de la form. Les cadres sont dessinés.

Une fois ajustée, j'ai placé l'appel dans les evenements OnEnter des objets ou dans l'evenement OnClick
d'un bouton, mais là rien ne ce passe !?

procedure TMainForm.Button3Click(Sender: TObject);
begin
Cadre(1,true,Edit1.BoundsRect, MainForm.Canvas);
end;

J'ai modifier la déclaration de la procedure Cadre en mettant en passage par variable CanvasDest
procedure TMainForm.Cadre(EpaisseurCadre : integer; Object_avec_Cadre : Boolean; ObjetRect : TRect;var CanvasDest : TCanvas);

Mais lors de l'appel j'ai ce message :
[Erreur] MAIN.PAS(222): Un objet constante ne peut être passé comme paramètre Var

Comment faire ?
Merci pour votre aide.

Jean
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 1 févr. 2011 à 17:14
3
Merci
Salut à tous,

moi je ferai un truc comme ça (testé Ok en MDI):
[hr]procedure FrameControl(aControl: TControl; Marge, Width: Integer; Color: TColor);

[b]var
  /baDC: HDC;
  aRect: TRect;
  I: Integer;
  aBrush: TBrush;
[b]begin
  /b// si le controle a un parent
  if Assigned(aControl.Parent) [b]then
    /baDC :=  GetDC(aControl.Parent.Handle)
  [b]else
  /b // sinon on utilise le bureau
    aDC : = GetDC(0);
  // on crée notre Brush
  aBrush :=  TBrush.Create;
  [b]try
    /b // affecte la couleur
    aBrush.Color : = Color;
    // on récupère la taille du controle a encadrer
    aRect :=  aControl.BoundsRect;
     // agrandit le rectangle de la valeur de Marge
    InflateRect(aRect, Marge, Marge);
    // on répete autant de fois que l'épaisseur voulue
     for  I : = 1 to Width [b]do
    begin
      /bInflateRect(aRect, 1, 1);
      FrameRect(aDC, aRect, aBrush.Handle);
    end;
  [b]finally
  /b// et on libère tout avant de quitter
    if Assigned(aControl.Parent) [b]then
      /bReleaseDC(aControl.Parent.Handle, aDC)
    [b]else
      /bReleaseDC(0, aDC);
    aBrush.Free;
  end;
end;

procedure TMainfrm.Button1Click(Sender: TObject);
[b]begin
  /bFrameControl(Edit1, 5, 3, clRed);
  FrameControl(Button1, 5, 3, clBlue);
  FrameControl(label1, 0, 4, $0096C7FC);
  FrameControl(panel1, 5, 2, clFuchsia);
end;
[hr]

bien sur si la fiche se redessine le cadre s'efface mais on peut facilement repérer le contrôle qui a le focus et l'encadrer depuis l'évènement OnPaint de la Fiche


[hr]@+Cirec
[hr]

Merci Cirec 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de Cirec
Meilleure réponse
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 2 févr. 2011 à 00:54
3
Merci
Re,

Et bein moi, je ferais finalement (à peu près) comme ça :)))


procedure TForm1.FormCreate(Sender: TObject);
  begin
  Shape1.Brush.Style := bsClear;//Ds l'inspecteur d'objets
  Shape1.Visible     := false;  //Ds l'inspecteur d'objets
end;


procedure FrameControl(Sender: TObject; Gap, Width, Color: Integer);
  var     Ctrl : TControl absolute Sender;
  begin
  if Ctrl.HasParent then Form1.Shape1.Parent :=  Ctrl.Parent;
  Form1.Shape1.Pen.Color := Color;
  Form1.Shape1.Pen.Width := Width;
  Form1.Shape1.SetBounds(Ctrl.Left-Gap-Width,Ctrl.Top-Gap-Width, Ctrl.Width+Gap+Gap+Width+Width, Ctrl.Height+Gap+Gap+Width+Width);
  Form1.Shape1.Show;
end;


//Exemples:
procedure TForm1.Button1Enter(Sender: TObject);
  begin
  FrameControl(Sender, 2, 5, clred);
end;

procedure TForm1.Label1Click(Sender: TObject);
  begin
  FrameControl(Sender, 2, 5, clred);
end;

procedure TForm1.Memo1Enter(Sender: TObject);
  begin
  FrameControl(Sender, 2, 5, clred);
end;



Je dis "à peu près" car c'est là qu'on s'aperçoit que les fiches MDI buguent et qu'on comprend pourquoi Microsoft déconseille fortement l'utilisation du modèle MDI et qu'il est 'deprecated'. En effet, vous remarquerez que les TShape.Left et TShape.Top déconnent un peu quand le control à encadrer se trouve sur la fiche. C'est facile à corriger mais je ne l'ai pas fait par fainéantise pour vous montrer . En revanche, ça roule quand le control a un parent ou sur une fiche SDI.


_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr

Merci Caribensila 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 92 internautes ce mois-ci

Commenter la réponse de Caribensila
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 1 févr. 2011 à 11:52
0
Merci
Bonjour,

je ferai comme ça :
procedure ChangeCadre;
var
i : integer;
     for i:= 0 to Self.ComponentCount do
     begin
       if Components[i] is TButton then
       begin
       // ton traitement
       end;
     end;
end;

de la même manière les autres composants peuvent être traités.

mais d'autres solutions vont arriver..

cantador
Commenter la réponse de cs_cantador
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 1 févr. 2011 à 13:56
0
Merci
quelques composants "Bouton" free, donnent aussi la possiblité de traiter dans leurs propriétés leur apparence lors du clic, du survol etc..

si tu souhaites changer le cadre du bouton qui recoit le clic, il faut cherche celui qui détient le sender :
procedure TForm1.ButtonClick(Sender: TObject);
begin
  if Sender is TButton then
   ///
end;



cantador
Commenter la réponse de cs_cantador
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 1 févr. 2011 à 14:13
0
Merci
Bonjour et merci, Cantador.

J'ai essayé ta solution, mais pas plus de succés. Cela m'a donc donné l'impression que j'ai en fait pas le droit de dessiné sur le canvas de la form principale. Ma form est de style fsMDIForm, j'ai changé en fsNormal. Et ma solution fonctionne bien, la tienne aussi ! Mais pourquoi, je ne peut pas faire ça avec le style fsMDIForm ?
Y'a des truc qui me dépasse.

Jean
Commenter la réponse de jderf
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 1 févr. 2011 à 15:14
0
Merci
Salut,

Avec une fiche MDI et un TBevel, tu peux faire un truc du genre :

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
  begin
  with Bevel1 do begin
    if ActiveControl <> nil then begin
      Left   :=  ActiveControl.Left   - 6;
      Top    :=  ActiveControl.Top    - 6;
      Width  :=  ActiveControl.Width  + 8;
      Height :=  ActiveControl.Height + 8;
      Show;
    end else  Hide;
  end;
end;

_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr
Commenter la réponse de Caribensila
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 1 févr. 2011 à 15:31
0
Merci
Je te signale au passage que seuls les descendants de TWinControl peuvent recevoir le focus.


_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr
Commenter la réponse de Caribensila
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 2 févr. 2011 à 10:03
0
Merci
Vous avez coupé la chic à jderf
Maintenant, il boude
médusé devant une telle abondance..


cantador
Commenter la réponse de cs_cantador
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 2 févr. 2011 à 11:25
0
Merci
Non, non je ne boude pas !

Je viens juste de lire vos messages, je vais prendre un peu de temps pour essayer et comprendre vos codes.

Je rebondit sur ta remarque Caribensila, Microsoft déconseille les MDI, mais comment remplacé ce fonctionnement ? Les pages control, un peu lourd quand les feuilles filles contiennent déja des pages control ?

En tout cas merci à tous.
Commenter la réponse de jderf
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 2 févr. 2011 à 12:03
0
Merci
Je viens de tester la version de Cirec :

 
procedure TMDIChild.Edit1Enter(Sender: TObject);
begin
  Refresh;
  FrameControl(Edit1, 4, 4, clBlue);
end;


Avec le petit refresh en amont, seul le cadre de l'objet actif est visible. Par contre y'a le problème du repaint dés qu'une autre fille recouvre partiellement la fille précédente puis fermée.


Dans la version de Caribensila, aucun problème, l'objet actif de la fille est directement encadré, si une autre feuille recouvre partiellement puis est fermée, tous est bien redessiné. Je vais essayé de comprendre le fonctionnement.

Encore merci, c'est sympa.
Commenter la réponse de jderf
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 2 févr. 2011 à 12:09
0
Merci
Les pages control, un peu lourd

du tout, les TpageControl sont fluides, faciles à mettre en oeuvre et permettent d'afficher beaucoup d'informations en peu de place.

cantador
Commenter la réponse de cs_cantador
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 2 févr. 2011 à 14:10
0
Merci
Oui Cantador, je suis d'accord et je les utilisent souvent à l'intérieur de feuille fille.
Mais remplacé le principe des feuille fille, par un page control, cela me semble un lourd à mettre en oeuvre.

Par exemple, dans une appli de gestion de véhicule en réparation, une feuille fille ouverte par véhicule et autant de feuille fille de type client (6 ou 8 feuilles ouvertes).
Cela implique d'avoir un PageControl, avec une création dynamique de Tabsheet de type 'véhicule' ou 'client'. Donc création à la voler de tabsheet de type différent avec de nombreux compo et une organisation différente et des liens avec la BD différents aussi. C'est que je veux dire par lourd.


Jean
Commenter la réponse de jderf
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 2 févr. 2011 à 15:11
0
Merci
@jderf
« Microsoft déconseille les MDI, mais comment remplacé ce fonctionnement ? »

D'abord, MDI fonctionne toujours malgré quelques bogues. Il n'est simplement plus soutenu. D'ailleurs des applications connues (PaintShop Pro, PhotoShop) continuent d'exploiter le système MDI.

Sinon, il est techniquement possible de simuler MDI tout en restant en mode SDI grâce au système de docking des fiches de Delphi, en tout cas pour l'aspect visuel.
Pour l'aspect implémentation, je trouve de toute façon le système SDI plus souple que MDI. En MDI, toutes les fiches créées sont en fait des 'soeurs'. En SDI, une fiche fille peut elle-même être parent d'autres fiches filles, etc...


_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr
Commenter la réponse de Caribensila
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 2 févr. 2011 à 15:28
0
Merci
@Caribensila

"système de docking des fiches", tu parles de la notion glisser-ancrer (docksite de la fiche). Tu géres comment l'état minimized des filles ? Si tu as un exemple ou une URL se je preneur.

Je ne connaisais pas ce type de déclaration
'var Ctrl : TControl absolute Sender;', c'est intéressant et puissant.

Jean.
Commenter la réponse de jderf
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 2 févr. 2011 à 15:51
0
Merci
Oui, c'est l'ancrage.
Je n'ai malheureusement pas d'exemple car je n'ai jamais codé ce genre d'application. Je ne suis qu'un amateur et je programme par hobby, me laissant guider par ma fantaisie...
D'ailleurs, les BDD sont du chinois pour moi et je ne contredirai jamais Cantador dans ce domaine...

Rendons à César...
'var Ctrl : TControl absolute Sender;'
C'est Guillemouze qui me l'a fait découvrir...

_______________________________________
Soutenez Wikimédia France aujourd'hui : http://dons.wikimedia.fr
Commenter la réponse de Caribensila
jderf 192 Messages postés mercredi 29 décembre 2004Date d'inscription 2 octobre 2014 Dernière intervention - 2 févr. 2011 à 16:42
0
Merci
Bon à charge de revanche alors, sur les BD, coté systeme, j'en connais un peu plus.
Commenter la réponse de jderf
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 3 févr. 2011 à 12:51
0
Merci
re,

@Caribensila: Bien vu

voici un exemple d'ancrage très simple mais très pratique, qui utilise un TPageControl et une méthode d'ancrage manuelle


[hr]@+Cirec
[hr]
Commenter la réponse de Cirec
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscription 27 mars 2018 Dernière intervention - 11 févr. 2011 à 14:36
0
Merci
Par exemple, dans une appli de gestion de véhicule en réparation, une feuille fille ouverte par véhicule et autant de feuille fille de type client (6 ou 8 feuilles ouvertes).

il y beaucoup de solutions pour traiter cette articulation

En fait,il s'agit en fait de gérer plusieurs relations 1-N ensemble.

Tu peux dans cette optique, te servir d'un TreeView avec plusieurs niveaux d'arborescence, léger, mais pas très facile à coder néanmoins.
ou encore le must pour moi :

le TcxGrid (de chez devexpress) qui peut être choisi en DBGrid
avec un nombre de niveaux très important.

Pour ma part, j'ai crée une appli avec 7 niveaux d'arborescences sans soucis..

jette un oeil sur le site, tu trouvera quelques exemples d'affichage assez impressionnants

cantador
Commenter la réponse de cs_cantador

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.