Rappeler une procedure OnMouseUp [Résolu]

- 6 janv. 2013 à 01:56 - Dernière réponse :
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 8 janv. 2013 à 14:20
Bonjour,
Dans une application Delphi 2006, j'ai écrit une procédure pour un événement OnMouseUp d'un TImage (un bouton).

procedure TFormMain.ImageMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Begin
...
end;

Celle-ci fonctionne très bien en réponse à un clic souris sur le TImage.
Mais comment faire pour rappeler ce code à un autre endroit de mon programme ?
En somme, simuler un clic sur cet objet Timage.
Je n'arrive pas à trouver les bons paramètres pour appeler cette procédure.

A l'avance merci pour vos suggestions et ... bonne année 2013 à tous.

Warbler
Afficher la suite 

Votre réponse

18 réponses

Meilleure réponse
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
9 mars 2018
- 6 janv. 2013 à 02:54
3
Merci
procedure TFormMain.Button1Click(Sender: TObject);
begin
  ImageMouseUp(TObject(Image), [mbLeft], [], 1, 1);
end;

________________________________________________________
besoin de câbles audio, vidèo, informatique pas cher ?

Merci f0xi 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de f0xi
Meilleure réponse
Messages postés
692
Date d'inscription
jeudi 17 avril 2008
Dernière intervention
14 septembre 2018
- 6 janv. 2013 à 08:29
3
Merci
Salut
ton premier code à cette allure :
procedure TFormMain.ImageMouseUp(Sender: TObject; Button: TMouseButton; 
Shift: TShiftState; X, Y: Integer); 
Begin 
  maProconmouse(para1,para2 ...);
end;

procedure TFormMain.maProconmouse(para1:integer,para2:xxxx ...);
begin
 ....
end;


ensuite il suffit de faire :
procedure TFormMain.Button1Click(Sender: TObject);
begin
  maProconmouse(para1,para2 ...);
end;





Dubois77
site perso

Merci dubois77 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de dubois77
Meilleure réponse
3
Merci
Bonjour,
Merci beaucoup pour vos réponses.

J'aurais préféré utiliser la proposition directe de fOxi, mais ça plante toujours au niveau des paramètres ImageMouseUp.
Je suis donc passé par une procédure intermédiaire comme proposé par dubois77 et ça fonctionne.

Je vais essayer de comprendre pourquoi la première proposition ne fonctionne pas.
Bonne journée,
Warbler

Merci Warbler69 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de Warbler69
Meilleure réponse
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 6 janv. 2013 à 13:07
3
Merci
  var     X, Y : Integer;
  begin
  X := 0;
  Y := 0;
  ImageMouseUp(TObject(Image), mbLeft, [], X, Y);

Merci Caribensila 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de Caribensila
Meilleure réponse
Messages postés
423
Date d'inscription
samedi 17 mai 2003
Dernière intervention
4 août 2018
- 6 janv. 2013 à 14:21
3
Merci
ImageMouseUp(nil, mbLeft, [], 0, 0);

Merci korgis 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de korgis
Meilleure réponse
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 7 janv. 2013 à 09:34
3
Merci
@Warbler69
J'aurais préféré utiliser la proposition directe de fOxi


Je trouve la solution de M. Dubois plus propre et plus structurée (n'en déplaise à f0xi qui reste de très bon conseil quand même...). D'une manière générale, dès que du code est utilisé plus d'une fois dans un programme, je préfère faire une procédure ou une fonction, plutôt que de bidouiller des appels à des événements de composants. M'enfin, ça n'est qu'un avis...


Simon

Merci sp40 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de sp40
Meilleure réponse
Messages postés
2233
Date d'inscription
mardi 10 décembre 2002
Statut
Modérateur
Dernière intervention
15 décembre 2014
- 7 janv. 2013 à 10:50
3
Merci
"dès que du code est utilisé plus d'une fois dans un programme, je préfère faire une procédure ou une fonction, plutôt que de bidouiller des appels à des événements de composants"
- C' est une très bon conseil!


Composants Cindy pour Delphi
Faites une donation.

Merci cs_MAURICIO 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de cs_MAURICIO
Meilleure réponse
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 7 janv. 2013 à 11:38
3
Merci
Oui, c'est un bon conseil à condition d'être conscient que cela plombe les performances et que, par exemple, c'est à éviter dans les boucles longues.

Merci Caribensila 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de Caribensila
0
Merci
Merci pour vos avis et commentaires.
J'ai adopté la solution "procédure" et ça fonctionne bien.
Cordialement
Commenter la réponse de Warbler69
Messages postés
4996
Date d'inscription
dimanche 26 février 2006
Statut
Modérateur
Dernière intervention
27 mars 2018
- 7 janv. 2013 à 14:13
0
Merci
Bonjour,

pour ma part, je préfère la solution f0xi, Caribensila, Korgis
lorsqu'elle est évènementielle..

cantador
Commenter la réponse de cs_cantador
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 7 janv. 2013 à 16:21
0
Merci
@Cari :
J'ai testé ce que tu disais dans l'unité suivante (saint Thomas, c'est moi ! ) :

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    CheckBox1: TCheckBox;
    Edit1: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    a : integer;
    procedure calculalacon;
    { Déclarations privées }

  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin
     Button1Click(self);
end;

procedure TForm1.calculalacon;
var
   i : integer;
begin
     for i := 0 to 100000000
         do inc(a);
     for i := 0 to 100000000
         do dec(a);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
     a := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   i, j : integer;
   rDuree,
   rStart,
   rEnd : real;
begin
     rStart := now;
     for j := 0 to 30 do begin
         if CheckBox1.Checked
            then calculalacon
         else begin
              for i := 0 to 100000000
                  do inc(a);
              for i := 0 to 100000000
                  do dec(a);
         end;
     end;
     rEnd := now;
     rDuree := rEnd - rStart;
     edit1.Text := FloatToStr(rDuree);
end;

end.


En moyenne, on a 6 centièmes de mieux en cliquant sur le button1 avec la procédure qu'en cliquant sur le button1 sans procédure (uh ?), et on a 4 centièmes de mieux qu'en cliquant sur le button2... J'ai testé sur XE2. Peux tu m'en dire un peu plus sur le plombage des perfs ? (ou c'est mon test qui est pourri ?)

Simon
Commenter la réponse de sp40
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 7 janv. 2013 à 16:42
0
Merci
@Simon
J'ai pas le temps de bien l'étudier maintenant, mais je ne comprends pas bien ton test au premier abord...

Toujours est-il qu'il m'arrive souvent de réintégrer des procédures dans une boucle pour améliorer les performances d'une application (parfois même des procédures Delphi genre Odd(), etc...).

Et voici un cas réel (voir la discussion avec Cirec dans les commentaires) ou le temps d'exécution varie du simple au double.
Commenter la réponse de Caribensila
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 7 janv. 2013 à 16:49
0
Merci
Ça a l'air un peu corsé... Je jetterai un œil dès que possible, promis.
Mon programme de test ne sert à rien, et à priori, il n'y a rien à comprendre... C'est juste pour faire une boucle et tester si un code qui est délocalisé dans une procédure s'exécute plus rapidement ou pas que s'il est dans la boucle.

Simon
Commenter la réponse de sp40
Messages postés
4304
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
9 mars 2018
- 7 janv. 2013 à 21:46
0
Merci
Il n'y a pas de bonne ou mauvaise méthodes.

A savoir que faire du procwarp c'est à double avantage et double désavantage dans l'apprentissage de la programmation :

1er avantage, ça éclaircie le code, le rendant plus compréhensible. à condition de maitriser l'écriture et les conventions de code.

2eme avantage, on sépare mieux les routines des GE, facilement transposable, on peux avoir des procédure multi-evenementielle. à condition de maitriser les principes de polyvalence du code.

1er inconvenance, ça rallonge le code, le rendant plus difficile à parcourir. nécessite d'aller chercher les déclarations (x2) et non d'avoir la routine directement par le biais de l'éditeur d’événement. Il est nécessaire de respecter plusieurs conventions d'écriture et de gestion du code source pour en faciliter la lécture (regrouper les évenements faisant appels au procwarp et mettre ce dernier avant ou aprés ce groupe. Utiliser les Regions de code).

2eme inconvenance, ça génère de nombreux call qui peuvent alourdir le programme voir le rendre peu performant si le procwarpping est abusif.


Dans le cas présent il est intéréssant de le développer :


{ ImagePixel }

function imagePixel(aBitmap: TBitmap; aPixelX, aPixelY: integer): TColor;
begin
  if assigned(aBitmap) then
    result := aBitmap.pixels[aPixelX, aPixelY]; // <-- hahaha lol ... utilise ScanLine hein.
end;

procedure TFormMain.ImageMouseUp(); // Oui !
begin
  LabelMouseSelect.Caption := format('$%.8x', [imagePixel(Image1.Picture.Bitmap, X, Y)]);
end;

procedure TFormMain.ButtonCornerClick(); // Oui !
begin
  LabelLeftTop.Caption     := format('$%.8x', [imagePixel(Image1.Picture.Bitmap, 0, 0)]);
  LabelLeftBottom.Caption  := format('$%.8x', [imagePixel(Image1.Picture.Bitmap, 0, Image1.Picture.Height-1)]);
  LabelRightBottom.Caption := format('$%.8x', [imagePixel(Image1.Picture.Bitmap, Image1.Picture.Width-1, 0)]);
  LabelRightTop.Caption    := format('$%.8x', [imagePixel(Image1.Picture.Bitmap, Image1.Picture.Width-1, Image1.Picture.Height-1)]);
end;

procedure TFormMain.ButtonProcessClick(); // NON ! SURTOUT PAS ! à moins d'aimer les process qui plombes 10 minutes.
var X, Y: integer;
begin
  for Y := 0 to Image1.Picture.Height-1 do
    for X := 0 to Image1.Picture.Width-1 do
      ListBox1.Items.Add(format('$%.8x', [imagePixel(Image1.Picture.Bitmap, X, Y)]));
end;


{ Image Pixels List }
procedure ImagePixelsList(aBitmap: TBitmap; aStrings: TString);
type
  PScanLine = ^TScanLine;
  TScanLine = array[0..0] of integer;
var X, Y, W, H: integer;
    P : PScanLine;
    B: TBitmap;
begin
  if not (assigned(aBitmap) and assigned(aStrings)) then exit;

  W := Image1.Picture.Width-1;
  H := Image1.Picture.Height-1;
  B := TBitmap.Create;
  try
    B.assign(aBitmap);
    B.PixelFormat := pf32bit;
    Strings.BeginUpdate;
    try
      Strings.Clear;
      for Y := 0 to H do
      begin
        P := B.ScanLine[Y];
        for X := 0 to W do
          Strings.Add(format('$%.8x', [P^[X]]));
      end;
    finally
      Strings.EndUpdate;
    end;
  finally
    B.Free;
  end;
end;

procedure TFormMain.ButtonProcessOptimizedClick(); // Oui !
begin
  ImagePixelList(Image1.Picture.Bitmap, ListBox1.Items);
end;



________________________________________________________
besoin de câbles audio, vidèo, informatique pas cher ?
Commenter la réponse de f0xi
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 8 janv. 2013 à 08:05
0
Merci
...Comme je disais :

« C'est bien mais c'est à éviter dans les boucles longues. »
Commenter la réponse de Caribensila
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 8 janv. 2013 à 09:12
0
Merci
@Cari :
Spécifiquement sous Delphi ou d'une manière générale ?

Simon
Commenter la réponse de sp40
Messages postés
2684
Date d'inscription
jeudi 15 janvier 2004
Dernière intervention
26 juillet 2018
- 8 janv. 2013 à 13:02
0
Merci
« @Cari : Spécifiquement sous Delphi ou d'une manière générale ? »


D'une façon générale l'appel d'une procédure ou d'une fonction a toujours un coût.
Mais il se peut que certains compilateurs gèrent nativement plus ou moins bien cela.
Sous Delphi, par exemple, il existe la directive INLINE qui remplace l'appel d'une fonction par le code compilé du corps de la fonction (VOIR Using the inline Directive). Mais, personnellement, je dois mal m'y prendre car je n'ai jamais su mettre en oeuvre cette directive. Ce serait pourtant pratique de favoriser la lisibilité du code sans négliger les performances !


Pour revenir sur ton test, je ne comprenais pas parce que tu y utilises en fait 2 boucles. Une dans le corps de la routine appelante, et l'autre dans la routine appelée. Et ça ne peut donner de bons résultats car l'essentiel des itérations se font dans la routine appelée.
Voici un bout de code qui met bien le principe de réintégration d'une routine dans une boucle en évidence :

procedure TForm1.FormCreate(Sender: TObject);
  begin
  Edit1.Text := '999999';
  Edit2.Text := '999999';
end;

function Cube(X: Integer): Integer;
  begin
  Result := X*X*X;
end;

procedure TForm1.Button1Click(Sender: TObject);
  var     i,C,X : Integer;
          Start, Elapsed : Int64;
  begin
  X := 123;
  Start := GetTickCount;
  for i := 0 to 100000000 do
    C := Cube(X); // <---  !!!
  Elapsed := GetTickCount-Start;
  if StrToInt(Edit1.Text) > Elapsed then Edit1.Text := IntToStr(Elapsed);
  //Meilleur temps: 406 milliseconds.
end;

procedure TForm1.Button2Click(Sender: TObject);
  var     i,C,X : Integer;
          Start, Elapsed : Int64;
  begin
  X := 123;
  Start := GetTickCount;
  for i := 0 to 100000000 do
    C := X*X*X; // <---  !!!
  Elapsed := GetTickCount-Start;
  if StrToInt(Edit2.Text) > Elapsed then Edit2.Text := IntToStr(Elapsed);
  //Meilleur temps: 62 milliseconds (6 fois + rapide!).
end;
Commenter la réponse de Caribensila
Messages postés
1293
Date d'inscription
mardi 28 octobre 2003
Statut
Contributeur
Dernière intervention
3 juillet 2015
- 8 janv. 2013 à 14:20
0
Merci
Ok, je comprends (et c'est un peu plus abordable que vos histoire de pixels... )
Je vais aussi jeter un oeil à INLINE. Merci pour les infos.

Simon
Commenter la réponse de sp40

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.