[Delphi] Eigen component (PopupMenu)

Pagina: 1
Acties:

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Hoi,

Ik ben bezig met een eigen popupmenu, met een aantal extraatjes (Gradient bar, Break optie die goed werkt :P en een mooie separator).

Alleen heb ik een probleem: Ik wil nu aan de MenuItems van die popupmenu ook een property toevoegen.
Alleen als ik dit doe:
code:
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
type

  TMyMenuItem = class;

  tMyBarPopupMenu = class(TPopupMenu)
  private
   ..
  public
    { Public declarations }
    Items: TMyMenuItem;
    constructor Create(AOwner: TComponent); override;
    ..
  published
    ..
  end;

  TMyMenuItem = class(TMenuItem)
  private  
    fSeparatorText: String;   
  published
    property SeparatorText: String read fSeparatorText write fSeparatorText;
  end;

procedure Register;

implementation

constructor tMyBarPopupMenu.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  OwnerDraw := True;
  Items := TMyMenuItem.Create(Self);
  ..
end;


Dan leegt hij ook mijn Items. Ze zijn er nog wel (Ze worden wel getoond), maar in de code is Items.Count ineens 0. Dus werkt mijn ItemDraw ook niet.
Hoe kan dat? Dat hij de items leeggooit?

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Wat geeft de compiler voor hints en warnings als ie jouw code compiled? Volgensmij gaat ie zeuren over TMyBarPopupMenu.Items. Er bestaat namelijk al een Items property in TMenu (waar TPopupMenu) van af leid. Jij overschrijft die doodleuk, maar voor TPopupMenu bestaat ie nog wel degelijk. Aangezien TPopupMenu zijn eigen Items property gebruikt en niet die van jouw, lijkt ie leeg voor hem.

Dus negeer nooit de warnings en hints van de compiler! Meestal hebben ze helemaal gelijk en is er wat mis met je code.

Je zal je Items variable anders moeten noemen voordat het gaat werken. Bovendien kan je beter een readonly property gebruiken ipv een public variable. Maar je variable anders noemen geeft niet het effect waar jij op gehoopt had, denk ik. Volgensmij is het ook helemaal niet nodig. Aangezien TMyMenuItem afleid van TMenuItem past ie ook makkelijk in de originele Items property van TPopupMenu. Je kan dan ook jouw Items: TMyMenuItem geheel weglaten. Als je in TMyBarPopupMenu bij de properties van TMyMenuItem wilt zal je m moeten typecasten. Of maak een property aan met een Getter waar dat in gebeurd.

We adore chaos because we like to restore order - M.C. Escher


  • Guillome
  • Registratie: Januari 2001
  • Niet online
Het hoort wel te kunnen, bij een ListView kon het wel. Ik heb ook een keer een ListView uitgebreid, met ook een eigen ItemSoort
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
TMyItems = class;

  TVirtualShellView = class(TListView)
  private
    ..
    ..
  public
    { Public declarations }
    Items        : TMyItems;
    ..
  end;

  TMyItems = class(TListItems)
  public
    procedure Clear;
  end;

En dit werkte prima.
De compiler geeft geen fouten, maar ik weet echt niet hoe ik het moet doen.

If then else matters! - I5 12600KF, Asus Tuf GT501, Gigabyte Gaming OC 16G 5080 RTX, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 26-05 11:18

alienfruit

the alien you never expected

Ja, maar een virtual listview slaat de items zelf niet op, dat moet je zelf regelen. :)

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Beste XLerator,

Allereerst wil ik je nog fijne kerstdagen toewensen. Ik zal mijn eerste verhaal iets uitgebreider uit de doeken doen, maar eerst iets over het geloofwaardigheidsprobleem dat ik kennelijk heb.

Als je mijn post history bekijkt zal je zien dat ik hier redelijk veel Delphi vragen beantwoord. Daar zitten ook redelijk wat correcte antwoorden tussen, naar blijkt. Nu moet jij maar voor jezelf bepalen of je vindt dat ik verstand heb van Delphi en of ik dus een betrouwbare bron ben. Als je van mening bent dat ik dat niet ben hoef je niet verder te lezen. Als je van mening bent dat ik wel enige kennis van zake rond Delphi heb kan je verder lezen.

Je hebt inderdaad gelijk dat de compiler er geen hint of warning over geeft. Dat verbaast mij opzich, maar het feit blijft dat het niet geheel zonder gevaren is wat je doet. Je moet begrijpen dat er al een property bestaat met die naam in de TPopupMenu klasse waar je vanaf leid. Daar kan je je niets van aantrekken als je wilt en dat doe je nu ook niet in jouw geval.

Maar ben je je er nu wel van bewust dat de TPopupMenu.Items en TMyBarPopupMenu.Items wel dezelfde naam hebben, maar twee totaal andere dingen zijn? En dat je TMyBarPopupMenu.Items pas ook vanaf TMyBarPopupMenu wordt geintroduceerd? De bestaande code uit TPopupMenu gebruikt nog gewoon de oude vertrouwde TPopupMenu.Items! Met andere woorden:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var 
  MyPopupMenu: TMyBarPopupMenu;
  PopupMenu: TPopupMenu;
begin
  MyPopupMenu := TMyBarPopupMenu.Create(Self);
  PopupMenu := MyPopupMenu;

  // Beide Items properties wijzen naar een andere variable en 
  // geven dus een andere waarde. Dat terwijl er maar 1 instantie 
  // is van TMyBarPopupMenu.
  MyPopupMenu.Items.Count;
  PopupMenu.Items.Count;

  // Ook dit pakt de 'oude' Items en niet die van jouw
  TPopupMenu(MyPopupMenu).Items.Count;
end;

Dat het bij de TListView wel werkt is meer geluk dan wijsheid.

Nu we het probleem gevonden hebben kunnen we aan een oplossing werken. Waarom wil je een eigen Items variable maken? Alleen omdat ie van een ander type is? Je ziet dat eerste item toch nooit, dus de extra functionaliteit die je wilt toevoegen aan de menu items heeft daar geen zin. De andere menu items kan je gewoon toevoegen zonder problemen, want TMyMenuItem leid gewoon af van TMenuItem. Wanneer je in je code specifiek gebruik wil maken van je eigen afgeleide kan je m gewoon typecasten. Desnoods maak je een extra property/functie die het typecasten al voor je doet. Je eigen Items variable/propery maken is, mijns inziens, de oorzaak van al je problemen en geheel onnodig. Het niet gebruiken ervan lost je problemen op en zorgt niet voor verlies van functionaliteit. Het lijkt mij een uitgemaakte zaak.

Met vriendelijke groet,
De Kerstman, euh...LordLarry

We adore chaos because we like to restore order - M.C. Escher