Rappeler une procedure OnMouseUp [Résolu]

Warbler69 - 6 janv. 2013 à 01:56 - Dernière réponse : sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention
- 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
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscriptionModérateurStatut 9 mars 2018 Dernière intervention - 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é 97 internautes ce mois-ci

Commenter la réponse de f0xi
Meilleure réponse
dubois77 692 Messages postés jeudi 17 avril 2008Date d'inscription 14 septembre 2018 Dernière intervention - 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é 97 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é 97 internautes ce mois-ci

Commenter la réponse de Warbler69
Meilleure réponse
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 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é 97 internautes ce mois-ci

Commenter la réponse de Caribensila
Meilleure réponse
korgis 424 Messages postés samedi 17 mai 2003Date d'inscription 4 août 2018 Dernière intervention - 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é 97 internautes ce mois-ci

Commenter la réponse de korgis
Meilleure réponse
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 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é 97 internautes ce mois-ci

Commenter la réponse de sp40
Meilleure réponse
cs_MAURICIO 2233 Messages postés mardi 10 décembre 2002Date d'inscriptionModérateurStatut 15 décembre 2014 Dernière intervention - 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é 97 internautes ce mois-ci

Commenter la réponse de cs_MAURICIO
Meilleure réponse
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 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é 97 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
cs_cantador 4996 Messages postés dimanche 26 février 2006Date d'inscriptionModérateurStatut 27 mars 2018 Dernière intervention - 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
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 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
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 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
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 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
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscriptionModérateurStatut 9 mars 2018 Dernière intervention - 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
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 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
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 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
Caribensila 2684 Messages postés jeudi 15 janvier 2004Date d'inscription 26 juillet 2018 Dernière intervention - 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
sp40 1293 Messages postés mardi 28 octobre 2003Date d'inscriptionContributeurStatut 3 juillet 2015 Dernière intervention - 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.