Avatar billede freeall Nybegynder
01. oktober 2006 - 17:31 Der er 7 kommentarer og
1 løsning

Procedure skal køre når der klikkes på et TImage komponent

Hej.

Jeg har et TImage komponent, og et array bestående af en record (måske en ny klasse?) der repræsenterer en knap på TImage'et. Når der bliver klikket på TImage'et så kører TImage.OnClick og i den funktion går jeg igennem mit array og ser om en knap's koordinater passer med der hvor musen er lige nu. Den del er såmænd nem nok, og den har jeg ingen problemer med.

Men problemet er at jeg også vil beskrive en procedure i mit record (måske klasse?) som jeg så kan få til at køre i TImage.OnClick.

Lad mig forklare i en slags pseudo kode.

Mit record:
  TMyButton = record
    x: integer;
    y: integer;
    width: integer;
    height: integer;
    NormalPic: TJPEGImage;
    MouseOverPic: TJPEGImage;
    MouseClickPic: TJPEGImage;
    procedure DoThisThingWhenClicked();
  end;

Mit array:
var
  MyButtonArray: array of TMyButton;


Den funktion jeg vil bruge når jeg indsætter et element i mit array:
procedure AddToMyButtonArray(x,y,width,height: integer;
                            PicNormal, PicMouseOver, PicMouseClick: TJPEGImage;
                            someProc());
begin
  SetLength(MyButtonArray);
  MyButtonArray[high(MyButtonArray)].x := x;
  MyButtonArray[high(MyButtonArray)].y := y;
  MyButtonArray[high(MyButtonArray)].height := height;
  MyButtonArray[high(MyButtonArray)].width := width;
  MyButtonArray[high(MyButtonArray)].NormalPic := PicNormal;
  MyButtonArray[high(MyButtonArray)].MouseOverPic := PicMouseOver;
  MyButtonArray[high(MyButtonArray)].MouseClickPic := PicMouseClick;
  MyButtonArray[high(MyButtonArray)].MouseClickPic := PicMouseClick;
  MyButtonArray[high(MyButtonArray)].DoThisThingWhenClicked() := someProc();
end;

Og her er så den funktion der tjekker om et billede er blevet klikket på. Har undladt at tjekke om det er blevet klikket, fordi jeg ikke har problemer med det og den del forstår jeg godt:
procedure TForm1.Image1Click(Sender: TObject);
var
  i: integer;
begin
  for i:=0 to high(MyButtonArray) do
  begin
    if {the current coordinates is within this button} then
    begin
      MyButtonArray[i].DoThisThingWhenClicked();
    end;
  end;
end;

Så, er der nogen der kan hjælpe?
Det er helt fint hvis løsningen er langt fra det jeg har lagt op til her. Men generelt, have nogle billeder (som knapper) på en TImage og så tjekke om de bliver klikket.

Mvh, Tobias
Avatar billede kroning Nybegynder
01. oktober 2006 - 19:31 #1
Har jeg ret i at det du mangler blot er en metode til at kunne angive en procedure/funktion som en parameter?
Avatar billede kroning Nybegynder
01. oktober 2006 - 19:36 #2
Hvis det er kan du ganske enkelt definere en procedure/funktion under Type således:

TMinProc = procedure(PhoneNumber : string;ContactInfo : TContactInfo) of object;

of object angiver at proceduren befinder sig i en klasse

du kan nu i din record definere en variable:

MinProc : TMinProc;
Avatar billede kroning Nybegynder
01. oktober 2006 - 19:40 #3
Hvorfor bliver jeg ved med at trykke på send inden jeg er færdig med at skrive?

Din AddToMyButtonArray ser så således ud:

procedure AddToMyButtonArray(x,y,width,height: integer;
                            PicNormal, PicMouseOver, PicMouseClick: TJPEGImage;
                            TMinProc);
Avatar billede freeall Nybegynder
01. oktober 2006 - 22:45 #4
Hej. Tak for svaret. Du har ret, men der sker nogle lidt andre ting end der skulle.

Mit TButtonEvent:
  TButtonEvent = procedure(var Name: TObject) of object;

Og så mit record, TMyButton:
  TMyButton = record
    Rect: TRect;
    NormalPic: TPicture;
    MouseOverPic: TPicture;
    MouseClickPic: TPicture;
    DoThis: TButtonEvent;
  end;

I min MainForm er der nu deklareret dette:
  private
    procedure Btn1Click(var name: TObject);
    procedure AddToMyButtonArray(newRect: TRect;
                                PicNormal, PicMouseOver, PicMouseClick: TPicture;
                                someProc: TButtonEvent);

Og procedurerne for det ser sådan ud:

procedure TMainForm.AddToMyButtonArray(newRect: TRect;
                            PicNormal, PicMouseOver, PicMouseClick: TPicture;
                            someProc: TButtonEvent);
begin
  SetLength(MyButtonArray, length(MyButtonArray)+1);
  with MyButtonArray[high(MyButtonArray)] do
  begin
    Rect := newRect;
    NormalPic := picNormal;
    MouseOverPic := PicMouseOver;
    MouseClickPic := PicMouseClick;
    DoThis := someProc;
  end;
end;

procedure TMainForm.Btn1Click(var name: TObject);
begin
  // do nothing for now
end;

I FormCreate prøver jeg så at køre dette:
  AddToMyButtonArray(Rect(0,0,40,50), pic1, pic2, pic3, Btn1Click(nil));
Hvilket ikke fungerer. pic1..3 er alle af typen TPicture. Men den fejler og debuggeren giver denne besked: Types of actual and formal var parameters must be identical.
Forstår det ikke helt, for jeg synes da de virker temmelig ens. Og hvis ikke, så burde den fejle et andet sted end lige her. Så kan du hjælpe lidt mere? Du skrev at når man bruger "of object" betyder det at det ligger i klassen. Det er grunden til at jeg lagde alle funktionerne i TMainForm. Er det rigtigt nok?

Rigtig mange tak for dit svar indtil videre :)
Avatar billede kroning Nybegynder
02. oktober 2006 - 00:14 #5
Dit kald skal se sådan ud:
AddToMyButtonArray(Rect(0,0,40,50), pic1, pic2, pic3, Btn1Click);

Evt. parametere til Btn1Click skal du først angive i din Image1Click procedure:

procedure TForm1.Image1Click(Sender: TObject);
var
  i: integer;
begin
  for i:=0 to high(MyButtonArray) do
  begin
    if {the current coordinates is within this button} then
    begin
      MyButtonArray[i].DoThis(Nil);
    end;
  end;
end;
Avatar billede freeall Nybegynder
04. oktober 2006 - 08:07 #6
Hej kroning.

Tak for svaret. Nu ved jeg ikke lige hvorfor jeg glemte at svare. Men faktisk vågnede jeg op, og heureka så kunne jeg (dum som jeg var inden det) godt se at Btn1Click("blehbla") selvfølgelig ville køre metoden Btn1Click med de parametre, i stedet for at pege på den. Og det var også det du skrev. Og det hjalp, så mange tak for det :) Ud over at den ikke vil acceptere nil. Så jeg giver den bare Sender i stedet og lader være med at bruge det i min Btn1Click funktion. Underligt brok, men ja.

Tak for det. Nu vil jeg gerne give dig nogle point, men kræver det ikke at du former et svar i stedet for en kommentar?
Avatar billede kroning Nybegynder
04. oktober 2006 - 13:06 #7
Der kommer et svar her. Hvis du alligevel ikke har noget at bruge name til i din Btn1Click hvorfor så ikke bare fjerne den så der ikke kræves nogle parameter.
Avatar billede freeall Nybegynder
04. oktober 2006 - 21:59 #8
Synes der var noget med at den brokkede sig hvis ikke jeg sendte noget med. Men det mindes jeg ikke lige. Kigger lige på det, selvom det er underordnet for om det trods alt fungerer :) Om koden er helt perfekt og pæn kommer så i anden række. Hvertfald mange tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester