Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - allen Komponenten rechtsklick zuweisen


Pferdenarr - Mi 25.01.12 15:29
Titel: allen Komponenten rechtsklick zuweisen
Hi,
ich möchte allen Komponenten (TButton, TLabel, TTabSheet, ...) bei denen die Tag Eigenschaft <> 0 ist ein Maus Rechtsklick Event zuweisen.
Mein Ansatz wäre bis jetzt der folgende:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm1.FormCreate(Sender: TObject);
var
  i,j : Integer;
begin
  with Application do
  for i := 0 to ComponentCount -1 do
  begin
    for j := 0 to Components[i].ComponentCount -1 do
    begin
      if Components[i].Components[j].tag <> 0 then // k.a.
    end;
  end;
end;

// Das Event welches jetzt nur für Button1 gilt, allen zuweisen deren Tag <> 0 ist
procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  //
end;


Wie kann ich das bewerkstelligen ?

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


zuma - Mi 25.01.12 15:35

na, in dem du das onMouseDownEvent anhängst ?


Delphi-Quelltext
1:
2:
if Components[i].Components[j].tag <> 0 then
 Components[i].Components[j].onMouseDown := DeinEvent;


zuma


Pferdenarr - Mi 25.01.12 15:40

'TComponent' enthält kein Element namens 'onMouseDown'

[DCC Fehler] Unit1.pas(56): E2003 Undeklarierter Bezeichner: 'onMouseDown'


jaenicke - Mi 25.01.12 16:02

Wenn du einmal nachgeschaut hättest wo OnMouseDown denn deklariert ist, hättest du gesehen, dass es AFAIK in TControl deklariert ist. Du musst also schauen, ob du ein TControl vor dir hast (xy is TControl) und es im Erfolgsfall auf TControl casten (TControl(xy).OnMouseDown := ...).

Nebenbei kannst du auch ControlCount und Controls benutzen, dann kannst du dir das alles sparen inkl. der verschachtelten Schleife.


Andreas L. - Mi 25.01.12 16:13

Eventuell sind noch nicht alle Komponenten erzeugt worden wenn das FormCreate-Ereignis aufgerufen wird. Ich würde den Code in Loaded ausführen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
  TForm1 = class(TForm)
  ...
  public
    procedure Loaded; override;
  end;

...

procedure TForm1.Loaded;
begin
  inherited Loaded;

  // Code...
end;


jaenicke - Mi 25.01.12 16:40

Loaded wird vor OnCreate ausgeführt. :zwinker:
Das würde auch anders keinen Sinn machen, da Loaded ausgeführt wird, wenn alle Komponenten geladen sind und OnCreate, wenn das Formular fertig erzeugt und initialisiert ist.


Pferdenarr - Mi 25.01.12 16:45


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
begin
  for i := 0 to ComponentCount - 1 do
    if (Components[i] is TControl) then TControl(Components[i]).OnMouseDown :=


Fehlermeldung: "[DCC Fehler] Unit1.pas(46): E2362 Auf protected-Symbol TControl.OnMouseDown kann nicht zugegriffen werden"


jaenicke - Mi 25.01.12 17:33

Ok, dann ist es da noch nicht veröffentlicht. Da musst du halt mal schauen ab wann es da ist. Das kann auch bei unterschiedlichen Komponenten unterschiedlich sein.


Pferdenarr - Do 26.01.12 09:47

Ich habe eine Lösung gefunden: http://www.swissdelphicenter.ch/de/showcode.php?id=1148


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:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
{
  This example shows how to assign a OnContextPopup event
  handler to all components at runtime using SetMethodProp().
  (Here: OnContextPopup event handler)
}


{
  Diese Beispiel zeigt, wie man mit Hilfe von SetMethodProp()
  allen Komponenten ein Ereignis (hier: OnContextPopup Ereignis)
  zur Laufzeit zuweisen kann.
}



  private
    { Private declarations }
    procedure AssignOnContextPopupEvent;
    procedure OnContextPopup(Sender: TObject; MousePos: TPoint;
     var Handled: Boolean);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses
  TypInfo;

procedure TForm1.OnContextPopup(Sender: TObject; MousePos: TPoint;
  var Handled: Boolean);
begin
  with Sender as TComponent do
    ShowMessage(Name + ' right-clicked!');
end;

procedure TForm1.AssignOnContextPopupEvent;
var
  i: Integer;
  PropInfo: PPropInfo;
  Method: TMethod;
  PEvent: ^TContextPopupEvent;
begin
  for i := 0 to ComponentCount - 1 do
  begin
    PropInfo := GetPropInfo(Components[i].ClassInfo, 'OnContextPopup');
    if (PropInfo <> niland (PropInfo^.PropType^^.Kind = tkMethod) then
    begin
      Method := GetMethodProp(Components[i], PropInfo);
      if not Assigned(Method.Code) then
      begin
        PEvent := @Method.Code;
        PEvent^ := OnContextPopup;
        Method.Data := Self;
        SetMethodProp(Components[i], PropInfo, Method);
      end;
    end;
  end;
end;

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