Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Compiler erkennt TControl.PopupMenu nicht (https://www.delphipraxis.net/137786-compiler-erkennt-tcontrol-popupmenu-nicht.html)

hoika 28. Jul 2009 18:10


Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

folgender Code wird nicht compiliert,
weil der Compiler PopupMenu moniert (existiert nicht).

Delphi-Quellcode:
procedure TForm_Base.SetExportPopMenu;
var
  iComponent      : Integer;
  Component       : TComponent;
  Control         : TControl;
begin
  for iComponent:= 0 to ComponentCount-1 do
  begin
    Component:= Components[iComponent];
    if (Component is TListView) or
       (Component is TVirtualStringTree) then
    begin
      Control:= TControl(Component);
      if Control.PopupMenu=NIL then   // hier meckert er
      begin
        PopupMenu:= TPopupMenu.Create(ListView);
        Control.PopupMenu:= PopupMenu;
      end;
Nehme ich statt dessen Control:= TControl(Component)

Delphi-Quellcode:
with Component as TControl do
      begin
        if PopupMenu=NIL then
        begin
          MyPopupMenu:= TPopupMenu.Create(Control);
          PopupMenu:= MyPopupMenu;
        end;
      end;
klappt es.

Ich hätte aber gern die 1. Code.
Ich mage dieses RTTI hier nicht so.

Es handelt sich um das Original TControl (unit Controls).


Heiko

DeddyH 28. Jul 2009 18:17

Re: Compiler erkennt TControl.PopupMenu nicht
 
Es gibt doch auch noch ControlCount, wenn ich nicht irre (hab gerade kein Delphi zur Hand).
Delphi-Quellcode:
procedure TForm_Base.SetExportPopMenu;
var
  iComponent      : Integer;
  Control         : TControl;
begin
  for iComponent:= 0 to ControlCount-1 do
  begin
    Control:= Controls[iComponent];
    if ((Control is TListView) or
        (Control is TVirtualStringTree)) and not Assigned(Control.PopupMenu) then
    begin
      PopupMenu:= TPopupMenu.Create(ListView);
      Control.PopupMenu:= PopupMenu;
    end;
  end;
end;
Wie angedeutet nur heruntergetippt.

hoika 28. Jul 2009 18:26

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

Controls: wieder was dazugelernt ;)

gleiche Fehlermeldung:
Assigned(Control.PopupMenu)

undefinierter Bezeichner PopupMenu

*ratlos*



Heiko

jbg 28. Jul 2009 18:33

Re: Compiler erkennt TControl.PopupMenu nicht
 
Da wird TControl.PopupMenu wohl protected sein :wink:

Hawkeye219 28. Jul 2009 19:22

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo Heiko,

deine zweiter Code im Beitrag #1 funktioniert nicht wirklich, es scheint nur so. Du setzt damit lediglich das Popup-Menü des Formulars und lieferst gleichzeitig ein schönes Beispiel für die Tücken der WITH-Anweisung.

Gruß Hawkeye

hoika 28. Jul 2009 19:35

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

das habe ich auch schon gemerkt.
Wie muss es denn richtig heissen ?

Ich dreh hier noch durch.
So eine Zeitverschwendung für das bischen Scheiss !! (Tschuldigung)

Warum findet der PopupMenu nicht ???

Wie soll ich dass denn sonst für einen ListView zur Laufzeit setzen ????

#Update:#
Nicht zu fassen, ist doch tatsächlich protected.


Heiko

FaTaLGuiLLoTiNe 28. Jul 2009 19:44

Re: Compiler erkennt TControl.PopupMenu nicht
 
Wenn du das PopupMenu nur für 2 bestimmte Komponententypen setzen willst dann wäre es doch auch nicht zuviel Aufwand, beide Fälle seperat zu behandeln, oder? Also erst auf TListView prüfen, im Erfolgsfall dann explizit nach TListView casten und Menü zuweisen. Dasselbe dann für TVirtualStringTree.

hoika 28. Jul 2009 20:22

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

der Code wird sich noch ändern.
Ich muss halt leider doch immer auf die jeweilige Komponente casten.

Erledigt.

#closed#


Heiko

uligerhardt 29. Jul 2009 08:07

Re: Compiler erkennt TControl.PopupMenu nicht
 
Zitat:

Zitat von hoika
#closed#

Ich muss trotzdem noch meinen Senf dazugeben. :mrgreen:

Zitat:

Zitat von hoika
Nicht zu fassen, ist doch tatsächlich protected

Sagt der Compiler auch recht deutlich:
Code:
[Pascal Fehler] Unit1.pas(91): E2362 Auf protected-Symbol TControl.PopupMenu kann nicht zugegriffen werden
Das ist glücklicherweise ein Standardproblem mit einer Standardlösung:
Delphi-Quellcode:
type
  THACK_Control = class(TControl);
 
  if THACK_Control(Control).PopupMenu = nil then
    THACK_Control(Control).PopupMenu := TPopupMenu.Create(Control);
Uli.

hoika 29. Jul 2009 08:39

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

ja dein Compiler sagt das, meiner noch nicht (D6) ;)

Wie soll das mit dem THackControl denn laufen,
wenn es auch von TControl abgeleitet ist ?
Es sei denn, du machst das property PopupMenu noch public.

Das gefällt mir aber gar nicht ...


Heiko

mirage228 29. Jul 2009 09:25

Re: Compiler erkennt TControl.PopupMenu nicht
 
Naja wenn Du es inline in der Methode machst...

Delphi-Quellcode:
procedure WhatEver;

  type
    TControlAccess = class(TControl)
    public
      property PopupMenu: ....;
    end;

var
  Control: TControl;
begin
  TControlAccess(Control).PopupMenu := ...;
end;
Alternativ könnte man doch die Eigenschaft über RTTI versuchen abzugreifen...

Viele Grüße

uligerhardt 29. Jul 2009 09:26

Re: Compiler erkennt TControl.PopupMenu nicht
 
Zitat:

Zitat von hoika
ja dein Compiler sagt das, meiner noch nicht (D6) ;)

Na, das ist ja schwach. :-)

Zitat:

Zitat von hoika
Wie soll das mit dem THackControl denn laufen,
wenn es auch von TControl abgeleitet ist ?
Es sei denn, du machst das property PopupMenu noch public.

Nö, das ist ja der Trick. Das:
Delphi-Quellcode:
type
  THACK_Control = class(TControl);
ist die komplette Typdefinition - keine Member, Property-Redeklarationen oder sonstwas.
Jetzt hast du eine Klasse in der aktuellen Unit - und innerhalb einer Unit beschränkt protected den Zugriff nicht - im Gegensatz zu "strict protected". D.h das Member PopupMenu von THACK_Control ist in der aktuellen Unit de facto public. Und wegen der einfach gestrickten Definition von THACK_Control ist ein TControl auch (fast :mrgreen:) ein THACK_Control, also geht auch der Cast i.O.

Zitat:

Zitat von hoika
Das gefällt mir aber gar nicht ...

Da ist nichts wirklich Gefährliches dran. Der Entwickler von TControl hat ja schon entschieden, dass er dir die Möglichkeit des Zugriffs auf PopupMenu gibt, indem er es protected gemacht hat.

uligerhardt 29. Jul 2009 09:31

Re: Compiler erkennt TControl.PopupMenu nicht
 
Zitat:

Zitat von mirage228
Delphi-Quellcode:
procedure WhatEver;

  type
    TControlAccess = class(TControl)
    public
      property PopupMenu: ....;
    end;

var
  Control: TControl;
begin
  TControlAccess(Control).PopupMenu := ...;
end;

Ob du
Delphi-Quellcode:
type
  THACK_Control = class(TControl);
oder
Delphi-Quellcode:
type
  THACK_Control = class(TControl)
  public
    property PopupMenu;
  end;
schreibst, macht null Unterschied.

Zitat:

Zitat von mirage228
Alternativ könnte man doch die Eigenschaft über RTTI versuchen abzugreifen...

Das würde vermutlich funktionieren, wäre aber mit Kanonen auf Spatzen geschossen - sowohl vom Codieren als auch von der Laufzeit her.

mirage228 29. Jul 2009 09:36

Re: Compiler erkennt TControl.PopupMenu nicht
 
Ja an das mit den "class friends" innerhalb einer Unit habe ich nicht gedacht, da sind unsere Lösungen natürlich völlig equivalent. :)

Also ich würde wohl bei dem selben Vorhaben wohl auch nicht RTTI nehmen, wollte das aber auch nicht ungenannt lassen... ;)

hoika 29. Jul 2009 09:38

Re: Compiler erkennt TControl.PopupMenu nicht
 
Hallo,

friend class, stimmt ;)
Netter Trick.

Kenne mich mit Delphi nicht so aus ;)


Heiko

uligerhardt 29. Jul 2009 09:43

Re: Compiler erkennt TControl.PopupMenu nicht
 
Zitat:

Zitat von mirage228
Ja an das mit den "class friends" innerhalb einer Unit habe ich nicht gedacht, da sind unsere Lösungen natürlich völlig equivalent. :)

Jo. 8)

Zitat:

Zitat von mirage228
Also ich würde wohl bei dem selben Vorhaben wohl auch nicht RTTI nehmen, wollte das aber auch nicht ungenannt lassen... ;)

Für etwas schwierigere Fälle ist das auch der gangbarere Weg.

Zitat:

Zitat von hoika
Kenne mich mit Delphi nicht so aus ;)

Man lernt nie aus.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz