AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Komponentenentwicklung Problem mit Run- und DesignTime
Thema durchsuchen
Ansicht
Themen-Optionen

Komponentenentwicklung Problem mit Run- und DesignTime

Ein Thema von BAMatze · begonnen am 23. Okt 2009 · letzter Beitrag vom 27. Okt 2009
Antwort Antwort
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#1

Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 10:48
Hallo und nochmal guten Tag,

noch ein kleines Problem, hab mir eine kleine Komponente geschrieben, die ich eigentlich mal wieder spassishalber (man kann sie ja eventuell noch mal in der Form verwenden) in mein Delphi 2007 Pro in der Toolpalette installieren wollte. Wenn ich dynamisch über die Unit diese verwende gibt es keine Probleme. Nach Installation kann man sie problemlos auf die Form ziehen und wenn man sie startet (ohne etwas zu verändern) klappt alles (man sieht die Trackbar auf der Form).
Jetzt war aber der Sinn, der Komponente, dass über dem Pin für die Trackbar ein Label läuft, welches die Position mit einen vorgegebenen Skalierungsfaktor verrechnet und anzeigt. Wenn ich also die published Property "Labeled" im Objektinspektor von false (default-Einstellung) auf true setze, dann zeigt er das Label auch an (DesignTime) aber beim Starten (RunTime) kommt dann eine Fehlermeldung.
Klar ist mir dabei, dass es anscheinend ein Problem damit gibt, dass zu dem Zeitpunkt, wo ein paar der Setter für das Label aufgerufen werden, die Trackbar (aufwelche diese teilweise zugreifen) noch nicht erzeugt wurde. Aber wie kann ich diese zwingen dies nicht zu tun? hab schon alles mit

  if assigned(Komponente) then ... versucht abzufangen, führt aber auch nur zu Problemen.

Hoffe jemand kann mir sagen, was ich da noch falsch mache.

Vielen Dank im Voraus
BAMatze

Package zum Testen im Anhang
Angehängte Dateien
Dateityp: zip testkomponenten_120.zip (285,3 KB, 12x aufgerufen)
2. Account Sero
  Mit Zitat antworten Zitat
Benutzerbild von MarcoWarm
MarcoWarm

Registriert seit: 10. Sep 2003
Ort: Großhennersdorf
532 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 11:15
Hi Matze,

Pack_eigene_Standartkomponenten fehlt leider im Archiv

Gruß
Marco
Marco Warm
TUO
TheUnknownOnes.net
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.008 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 11:39
Einige grundsätzliche Empfehlungen für den Komponentenbau:
- trenne Runtime und Designtime Package
- erzeuge die eingebetteten Controls einmal im Konstructor deiner Komponente und benutze dies Visible Eigenschaft um die Sichtbarkeit zu regeln
- arbeite an einigen Stellen mit der Eigenschaft ComponentState, welche dir angibt, ob du gerade im Design Modus bist oder obs das laufende Programm ist (und einiges mehr) wenn du unterschiedliches Verhalten während Run- und Designtime möchtest.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 12:30
@Stevie: Das mit dem Trennen hab ich auch schon öfters gelesen, nur leider hab ich noch kein wirklich gutes Beispiel mal gesehen, wo dies konsequenter Weise dargestellt ist. Deswegen ist es für mich auch relativ schwer nachzuvollziehen, wie ich das adequat selber so programmiere. Meist hab ich das immer nach dem Prinzip "try and error" in einem einzigen Package programmiert. Ab und zu sind dort schon an der ein oder anderen Stellen die Componentstate´s zum Tragen gekommen. Nur wie dort jetzt eine "Trennung" stattfinden könnte, das ist für jemanden, der sowas noch nicht gemacht hat, meist schwer selber heraus zu finden.

@MarcoWarm Package ist im Anhang.
Angehängte Dateien
Dateityp: zip standardkomponenten_925.zip (445,4 KB, 9x aufgerufen)
2. Account Sero
  Mit Zitat antworten Zitat
fajac

Registriert seit: 1. Jul 2009
60 Beiträge
 
#5

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 12:57
Die Trennung in Designtime- und Runtime-packages ist immer dann sinnvoll, wenn die Komponente in beiden Umgebungen unterschiedliche Ressourcen verwendet. Wenn du beispielsweise zur Entwurfszeit selbsterstellte PropertyEditors verwendest (z.B. so etwas wie der Feldeditor von TTable), sollten die auch nur im Runtime-package drin sein.
  Mit Zitat antworten Zitat
Tryer

Registriert seit: 16. Aug 2003
200 Beiträge
 
#6

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 23. Okt 2009, 15:30
Im Setter führe ich Aktioneneigentlich immer nur dann aus, wenn der Wert sich auch verändert hat. Dadurch läßt sich hier z.B. ein zirkulärer Aufruf von SetValue und TrckChange stoppen.

Delphi-Quellcode:
procedure TLabTrackBar.TrckBarAnpassung(TrackBar: TMouseTrackBar);
begin
  TrackBar.Width := Width - 20;
  TrackBar.Height := Height - 15;
  TrackBar.Left := 10;
  TrackBar.Top := 12;
  if Assigned(FLblTrckBar) and Assigned(FTrckBar) then
  begin
    FLblTrckBar.Caption := floattostr(FTrckBar.Position * FScaleFactor) + FsLabelAdd;
    LblAnpassung(FLblTrckBar);
  end;
end;

procedure TLabTrackBar.LblAnpassung(FLabel: TLabel);
begin
  if Assigned(FLblTrckBar) and Assigned(FTrckBar) then
    FLblTrckBar.Left := Round((FTrckBar.Left + 11 - FLblTrckBar.Width / 2) +
      (FTrckBar.Position / (FTrckBar.Max - FTrckBar.Min) * (FTrckBar.Width - 22)));
end;

procedure TLabTrackBar.Resize;
begin
  inherited Resize;
  TrckBarAnpassung(FTrckBar);
  // LblAnpassung(FLblTrckBar); unnötig, geschieht in TrckBarAnpassung.
  // warum werden überhaupt die eigenen Felder übergeben?
end;

procedure TLabTrackBar.SetValue(dValue: Double);
begin
  if dValue <> FdValue then
  begin
    FdValue := dValue;
    if Assigned(FTrckBar) then
      FTrckBar.Position := Round(FdValue / FScaleFactor);
    LblAnpassung(FLblTrckBar);
  end;
end;

procedure TLabTrackBar.TrckChange(Sender: TObject);
begin
  SetValue(FTrckBar.Position * FScaleFactor);
end;
Grüsse, Dirk
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#7

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 27. Okt 2009, 08:31
Hallo an euch und danke für eure Posts, bin leider erst jetzt wieder dazu gekommen, hieran weiter zu arbeiten, da ich an einem 2. Projekt gerade arbeite un zusätzlich noch eine Abschlussarbeit in meinem Studium habe. Also Fulltime geplagt . Also @Dirk, werde ich gleich mal umsetzen, was du dort geschrieben hast. zu deiner Frage, wegen der Übergabe des eigenen Feldes: Habe ich mir deswegen so angewöhnt und umgesetzt, wenn ich mal mehr als eine gleiche Komponente (z.B. TTrackbar habe), damit ich alle dann in einer Procedure abhandeln kann und damit die Procedure dann weiß, welche der Komponenten es bearbeiten soll, übergebe ich sie dieser. Sicherlich ist es Ansichtssache/ Geschmackssache, ob dies gut oder schlecht ist, im Endeffekt teste ich einfach bestimmte Vorgehensweisen und versuche den für mich verständlichsten Weg zu finden. In dem Fall (ist ja nur ein Trackbar) ist es sicherlich unangebracht.

Falls jemand nochmal ein gutes (klein und verständliches) Beispiel kennt, für Trennung von Run- und DesignTime wäre ich dankbar, wenn ihr dies posten könntet.

Vielen Dank
BAMatze

[Edit] Problem bleibt leider bestehen, dass ich ein Problem habe beim Zugriff bei den Settern anscheinend allgemein.

Trotz Änderung gemäß Dirk:
Delphi-Quellcode:
procedure TLabTrackBar.SetLabeled(bWert: Boolean);
begin
  if bWert <> FbLabeled then
    begin
      case bWert of
      true: begin
              FLblTrckBar := CreateLabel(floattostr(FtrckBar.Position*FScaleFactor) + FsLabelAdd);
              LblAnpassung(FLblTrckBar);
            end;
      false: FreeandNil(FLblTrckBar);
      end;
      FbLabeled := bWert;
    end;
end;
[/Edit]
2. Account Sero
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
934 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 27. Okt 2009, 18:52
Hi,

irgendwie scheint es, ohne Nahe zu treten zu wohlen, das du mit get und set ganz allgemein
ein Problem hast.

Beispiel:
Zitat:
Wenn ich also die published Property "Labeled" im Objektinspektor von false (default-Einstellung) auf true setze, dann zeigt er das Label auch an (DesignTime) aber beim Starten (RunTime) kommt dann eine Fehlermeldung.
Davon ist aber im Code nichts zu sehen:
Delphi-Quellcode:
...
property Labeled: boolean read GetLabeled write SetLabeled;
...
sollte dann wohl so aussehen:
Delphi-Quellcode:
...
property Labeled: boolean read GetLabeled write SetLabeled default false;
...
Weiter geht es mit GetLabeled, statt so:
Delphi-Quellcode:
function TLabTrackBar.GetLabeled;
begin
  result := FbLabeled;
end;
lieber so:
Delphi-Quellcode:
function TLabTrackBar.GetLabeled;
begin
  if Assigned(FLblTrckBar) then result := FbLabeled
                           else Result := false;
end;
Und bei SetLabeled, statt so:
Delphi-Quellcode:
procedure TLabTrackBar.SetLabeled(bWert: Boolean);
begin
  case bWert of
  true: begin
          FLblTrckBar := CreateLabel(floattostr(FtrckBar.Position*FScaleFactor) + FsLabelAdd);
          LblAnpassung(FLblTrckBar);
        end;
  false: FreeandNil(FLblTrckBar);
  end;
  FbLabeled := bWert;
end;
doch wohl eher so:
Delphi-Quellcode:
procedure TLabTrackBar.SetLabeled(bWert: Boolean);
begin
  if FbLabeled <> bWert then
  begin
    FbLabeled := bWert;
    if FbLabeled then
    begin
      FLblTrckBar := CreateLabel(floattostr(FtrckBar.Position*FScaleFactor) + FsLabelAdd);
      LblAnpassung(FLblTrckBar);
    end
    else FLblTrckBar.Free;
  end;
end;
Nun zu Design- und Runtime:

Ich persönlich nutze den kleinen Unterschied ganz gerne, wenn ich in einer Komponentensammlung
intern wiederholt von gleichen Komponenten ableite, aber trotzdem einzelne Komponenten nutzen/veröffentlichen
möchte.

Auch hierzu ein Beispiel:

Benötigt wird die Möglichkeit ein TPanel sichtbar/unsichtbar machen und darauf reagieren zu können.

Daraus folgt:

Delphi-Quellcode:
...
TVisibleChangeEvent = procedure (Value : Boolean) of object;
...
  TCustomPanel = class (TPanel)
  private
    FOnChangeVisible: TVisibleChangeEvent;
    function GetVisible: Boolean;
    procedure SetVisible(Value: Boolean);
  public
    property OnChangeVisible: TVisibleChangeEvent read FOnChangeVisible write
            FOnChangeVisible;
    property Visible: Boolean read GetVisible write SetVisible;
  end;
...
implementation
...
function TCustomPanel.GetVisible: Boolean;
begin
  Result := TControl(Self).Visible;
end;

procedure TCustomPanel.SetVisible(Value: Boolean);
begin
  TControl(Self).Visible := Value;
  if Assigned(FOnChangeVisible) then FOnChangeVisible(Value);
end;
...
Da ich innerhalb der Unit noch andere Objekte davon ableiten möchte, sind die properties nur public.
Das Sichtbar machen für den User und damit für den Objektinspector erfolgt gesondert,
und zwar in der Art, das ich ein weiteres Objekt im Interface-Teil deklariere:
Delphi-Quellcode:
TVisblePanel = class (TCustomPanel)
published
  property OnChangeVisible;
  property Visible;
end;
Welchen Vorteil habe ich dadurch?

Ganz Einfach, ich kann innerhalb der Unit bzw. der Komponentensammlung auf die deklarierten
Eigenschaften der Objekte zugreifen.

Innerhalb einer Unit, also mehrere Objekte mit dem gleichen Vorfahren kein Problem:
Delphi-Quellcode:
...
   TCustomPanel = class(TGraphicControl)
   private
     FsLabelAdd: TLabel;
   ...
   end;

   TButtonPanel = class(TCustomPanel)
   ...
   end;
...
implementation
...
procedure TButtonPanel.SetVisible(Value: Boolean);
begin
  TControl(Self).Visible := Value;
  FsLabelAdd := 'XX';
end;
...
.

Und wenn beide Objekte in verschiedenen Units sind? Zugriff nicht möglich!

Daher also, eher so:

Delphi-Quellcode:
...
   TACustomPanel = class(TCustomPanel)
   private
     FsLabelAdd: TLabel;
     procedure SetLabelAdd(Value : String);
     function GetLabelAdd : String;
   ...
   protected
     property LabelAdd: string read GetLabelAdd write SetLabelAdd;
   end;

   TButtonPanel = class(TACustomPanel)
   ...
   end;
...
implementation
...

procedure TButtonPanel.SetLabelAdd(Value: String);
begin
 if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd := Value;
end;
...

procedure TButtonPanel.GetLabelAdd : String;
begin
  if Assigned(TControl(Self).LabelAdd) then Result := TControl(Self).LabelAdd.Visible
                                       else Result := '';
end;

procedure TButtonPanel.SetButtonVisible(Value : Boolean);
begin
  if Assigned(FButton) then
  begin
    FButton.Visible := Value;
    if FButton.Visible then
     if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd := 'mm';
  end
  else
  if Assigned(TControl(Self).LabelAdd) then TControl(Self).LabelAdd.Free;
end;
Was erreiche ich dadurch?

Ich stelle in den Komponenten/Objekten nur die Eigenschaften in dem Sichtbarkeitsbereich zur Verfügung
die ich als Entwickler auch wünsche und unterbinde auf alle anderen den Zugriff von außen.
Qualitativ stelle ich so mit das zu erwartende Verhalten der Komponenten/Objekte sicher,
nicht nur für mich, sondern auch für andere.

Der Code für den Zugriff innerhalb einer Unit ist das schlechtere Beispiel, da die Owner-Komponente nicht
mitbekommt das sich die Sichtbarkeit des Labels geändert hat, daher immer das Beispiel verwenden,
dass die Möglichkeit der Nutzung in verschiedenen Units ermöglicht!

Registriert werden im Abschluss nur die Komponenten/Objekte deren Eigenschaften auch published sind.

Alles klar?

viele Grüße

Alter Mann

PS Der Code dient nur zur Veranschaulichung und ist nicht getestet!!!
  Mit Zitat antworten Zitat
BAMatze

Registriert seit: 18. Aug 2008
Ort: Berlin
759 Beiträge
 
Turbo Delphi für Win32
 
#9

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 27. Okt 2009, 19:32
Also @Alter Mann danke dir schonmal für diese ausführliche Erklärung. Muss das sicherlich noch 2 bis 3 mal durchlesen, damit ich alles auch 100% verstehe aber echt Klasse, habe sowas in der Art noch nirgendswo gesehen. Werde es morgen auf Arbeit umsetzen.

2. Account Sero
  Mit Zitat antworten Zitat
Roaster

Registriert seit: 21. Jul 2004
Ort: bei mir zu Hause
107 Beiträge
 
#10

Re: Komponentenentwicklung Problem mit Run- und DesignTime

  Alt 27. Okt 2009, 21:25
Zitat von Stevie:
Einige grundsätzliche Empfehlungen für den Komponentenbau:
- trenne Runtime und Designtime Package
Genau hier frage ich mich, warum ich das machen soll. Wenn ich kommerzielle Sammlungen wie die von TMS ansehe, dann wird dort nicht zwischen Runtime und Designtime unterschieden. Wenn ich mir hingegen die Components von Bergsoft (NextSuite) näher betrachte, dann werden hier sowohl Runtime und Designtime ausgeliefert und es wird empfohlen beide in der IDE zu installieren.

Kann hier jemand deshalb eine Empfehlung abgeben wann was sinnvoll erscheint? Ach ja, dann kenn ich noch die Sammlung mit den Windows 7 Komponenten, die ebenfalls nur als Designtime(?) ausgeliefert werden.
cu, Michael

Windows 7, WinXP Pro, Vista, WinXP Home, Win98 SE
D4 C/S, D7 Enterprise, Turbo Delphi Pro, Delphi 2009
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz