Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TShape dynamisch OnClick-Routine zuweisen


Jakob Schöttl - Di 21.08.07 09:43
Titel: TShape dynamisch OnClick-Routine zuweisen
Hallo mal wieder,
wenn ich einem dynamisch erzeugten Shape: TShape eine Ereignisbehandlungsroutine für OnClick zuweisen will kommt folgende Fehlermeldung:


Quelltext
1:
[Fehler] Unit1.pas(114): E2362 Auf protected-Symbol TControl.OnClick kann nicht zugegriffen werden                    


Aber TShape besitzt doch das Ereignis OnClick!?
Ich hoffe ihr könnt mir helfen.

Quellcodeauszug:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
//Deklaration TForm1:
  private
    Shapes: array [0..9,0..9of TShape;
    procedure ShapesClick(Sender: TObject);

//On Form1Create:
  Shapes[n,m].OnClick := Self.ShapesClick;


Narses - Di 21.08.07 09:50
Titel: Re: TShape dynamisch OnClick-Routine zuweisen
Moin!

user profile iconJakob Schöttl hat folgendes geschrieben:
wenn ich einem dynamisch erzeugten Shape: TShape eine Ereignisbehandlungsroutine für OnClick zuweisen will kommt folgende Fehlermeldung:


Quelltext
1:
[Fehler] Unit1.pas(114): E2362 Auf protected-Symbol TControl.OnClick kann nicht zugegriffen werden                    


Aber TShape besitzt doch das Ereignis OnClick!?

Also in meinem ObjectInspector hat ein TShape kein OnClick-Ereignis; wie kommst du darauf? :nixweiss:

Nimm halt OnMouseDown. :idea: ;)

cu
Narses


Jakob Schöttl - Di 21.08.07 11:06
Titel: Re: TShape dynamisch OnClick-Routine zuweisen
user profile iconNarses hat folgendes geschrieben:
Also in meinem ObjectInspector hat ein TShape kein OnClick-Ereignis; wie kommst du darauf? :nixweiss:

Ja stimmt, im Objektinspektor hab ich nicht nachgeschaut, weil ich die Shapes ja dynamisch erzeugen wollte.
Aber in der Delphi-Hilfe stand eben zu TShape,
Zitat:
OnClick Wird ausgelöst, wenn der Benutzer auf das Steuerelement klickt.


ok, OnMouseDown funktioniert aber. Danke.


KlausNeu - So 15.06.08 16:34

Hi,

wieso klappt das bei mir nicht? Ich erzeuge shapes (18*6) und möchte dann auf die OnMouseDown-Ereignisse reagieren, und zwar mit einer eigenen Routine, die mir Zeile und Spalte liefern soll (als Variable) und dann soll das entsprechende shape auch noch die Farbe wechseln. Im Augenblick krieg ich den Code aber nicht mal compiliert. Es kommt immer: Inkompatible Typen:Liste der Parameter ist unterschiedlich. Das Komische ist, als ich es noch mit OnClick (vergl. Beoiträge oben) probierte, ging es, allerdings kam dann nur die Meldung, wenn ich TForm1 anklickte.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TForm1 = class(TForm)
    Shape1: TShape;
    procedure FormCreate(Sender: TObject);
    procedure MDown(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}

    shape_array : array[1..18,1..6of TShape;
    hoehe, breite : integer;
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var n, m : integer;
begin
     hoehe := 20;
     breite := 40;
     // Shapes erzeugen in Schleife
     for n := 1 to 18 do begin;
         for m := 1 to 6 do begin;
             shape_array[n,m]:= tShape.Create(Self);
             with shape_array[n,m] do
             begin
                  parent := self;
                  left := 100 + (m-1)* breite;
                  top  := n * hoehe;
                  height := hoehe;
                  width := breite;
                  brush.color := clWhite;
                  onMouseDown := MDown;
             end;
          end;
     end;
end;
                             
procedure TForm1.MDown(Sender: TObject);
begin
     Showmessage('OKIDOKI');
end;
end.


Falls das irgendwann mal klappt, wie kriegt ich die Indizes raus?
Gruß Klaus

Moderiert von user profile iconAXMD: Quote- durch Delphi-Tags ersetzt


Narses - So 15.06.08 17:04

Moin!

Die Methode OnMouseDown hat andere Parameter, als die OnClick-Methode; schau einfach mal dazu in die DOH. :les: :think: ;)

cu
Narses


Yogu - So 15.06.08 17:26
Titel: Re: TShape dynamisch OnClick-Routine zuweisen
user profile iconJakob Schöttl hat folgendes geschrieben:
Aber in der Delphi-Hilfe stand eben zu TShape,
Zitat:
OnClick Wird ausgelöst, wenn der Benutzer auf das Steuerelement klickt.

Da müsste ein Symbol für "Protected" davor stehen - das Ereignis ist vorhanden, aber verborgen. Du müsstest eine neue Komponente von TShape ableiten und die Eigenschaft als published oder public markieren:


Delphi-Quelltext
1:
2:
3:
4:
TClickableShape = class(TShape)
published
  property OnClick;
end;

Grüße,
Yogu


KlausNeu - So 15.06.08 17:39

Sorry, aber ich steh auf der Leitung. Was für parameter denn? Das versteh ich schon nicht in der Fehlermeldung. Muss ich da noch was angeben? DOH funktioniert bei mir auch nicht, krieg Fehlermeldung, noch nicht mal das klappt.
Gruß Klaus

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Hi,

ich steh nicht mehr auf der Leitung! Natürlich müssen in der procedure-Declaration die x- und y-Parameter stehen!! Klappt jetzt auch. Aber wie kriege ich raus, welches shape das angeklickte ist?

Gruß Klaus


Narses - So 15.06.08 17:48

Moin!

user profile iconKlausNeu hat folgendes geschrieben:
Aber wie kriege ich raus, welches shape das angeklickte ist?
Du merkst dir z.B. in der Eigenschaft .Tag des Shapes die ldf. Erzeugungsnummer und kannst dann daraus die Koordinaten ableiten. :idea:

cu
Narses


Yogu - So 15.06.08 17:50

Hallo,


Definition von OnClick
1:
procedure(Sender: TObject);                    



Definition von OnMouseDown
1:
procedure(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);                    

Jetzt ein bisschen klarer? [delphi]OnClick[/delhpi] erwartet nur den Parameter Sender, OnMouseDown dagegen noch Button, Shift, X und Y.

Gott sei Dank gibt es für die Delphi-Codes auch noch die Symbolleiste...

_____________________________________

Das lösch ich jetzt nicht mehr! ;)

user profile iconKlausNeu hat folgendes geschrieben:
ich steh nicht mehr auf der Leitung! Natürlich müssen in der procedure-Declaration die x- und y-Parameter stehen!! Klappt jetzt auch. Aber wie kriege ich raus, welches shape das angeklickte ist?

Benutze einfach die Eigenschaft Sender. Wenn du die mit den Komponenten vergleichst, bekommst du den "Sender" raus.

Grüße,
Yogu


KlausNeu - So 15.06.08 18:05

Hallo,

ich komme der Sache schon näher, aber wie spreche ich das an?
Ich hab jetzt beim Erzeugen in der Schleife eingefügt:
Zitat:
tag := (n-1)*18 + m;

und in der OnMouseDown-Routine:
Zitat:
showmessage(inttostr(tag));

Da kommt natürlich immer 0. Eigentlich müsste ich ja jetzt was in der Art schreiben: shape_array[a,b].tag usw. um das ansprechen zu können. a und b muss ich aber erst aus tag ermitteln!? Oder steh ich schon wieder (immer noch?) auf der Leitung?

Gruß Klaus


Yogu - So 15.06.08 18:19

Hallo,

so ermittelst du die Tag-Eigenschaft der Form, deshalb kommt auch immer 0 raus. Richt ist:


Delphi-Quelltext
1:
shape_array[TComponent(Sender).Tag div 18, TComponent(Sneder).Tag mod 18;                    

Du musst den Sender in eine Komponente umwandeln, deren Tag auslesen und dann die niedrigen und hohen Teile auslesen. Wenn du z.B. 36 durch 18 teilst, kommt 2 raus. Der Rest (mod) bleibt 0. Bei 40 kommen 18 und 4 raus.

Grüße,
Yogu


KlausNeu - So 15.06.08 18:43

Klasse, danke,jetzt funzts, hier Frabwechsel beim Klicken:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.MDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
  var a, b : integer;
begin
     a := (TComponent(Sender).Tag div 18 ) + 1;
     b := TComponent(Sender).Tag mod 18;
     if shape_array[a,b].brush.color = clWhite
        then shape_array[a,b].brush.color := clRed
        else shape_array[a,b].brush.color := clWhite;
end;


Vielen Dank, Klaus.

Moderiert von user profile iconAXMD: Quote- durch Delphi-Tags ersetzt