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 größe der Komponente automatisch anpassen (https://www.delphipraxis.net/133862-groesse-der-komponente-automatisch-anpassen.html)

BAMatze 11. Mai 2009 07:47


größe der Komponente automatisch anpassen
 
Hallo und guten Morgen an alle DP´ler,

hab mal wieder eine Frage an die etwas versierteren Programmierer unter euch. Ich verwende mehrfach eine Kombination aus 1 Label und 1 Edit. Diese haben immer gemeinsame Zusammenhänge. Deswegen möchte ich sie als eine Komponente schreiben und diese dann nur in meinem Projekt draufziehen. Soweit so gut. Jetzt möchte ich aber aus übungstechnischem Sinne dass die größe der TWincontrol in die ich das ganze packe seine Größe an die Schriftgröße der im Edit und Label verwendeten Schriftgröße anpasst.

Ok habe zu diesem Thema auch ein wenig Reschaschiert und etwas über ein TPresistent gelesen, in die man wohl die "Eigenschaften" der Komponente (wenn ich das richtig verstanden habe) packt. Ist dies sinnvoll oder wie würdet ihr die Größenanpassung vornehmen?

Vielen Dank
BAMatze

Flips 11. Mai 2009 08:04

Re: größe der Komponente automatisch anpassen
 
Hi,

warum das Rad neu erfinden, such ma nach der Komponente TLabeledEdit.
lg, Flips

oki 11. Mai 2009 08:07

Re: größe der Komponente automatisch anpassen
 
Moin BAMatze,

als erstes würde ich dir empfehlen dir die Komponente LabeledEdit anzuschauen. Die wird von Hause aus in Delphi mitgeliefert.
Das nächste Thema Größenanpassung. Du kannst natürlich auf die Änderung des Fonts reagieren. Ich glaube da gibt es eine protected Methode die du überscheiben kannst um auf die Änderung der Fontgröße zu reagieren. Müßte ich aber noch mal suchen um den Code zu finden wo ich sowas mal gemacht habe.

Das Thema TPersistent in deinem Post soll sicher die Implementation eines Wrappers sein. Da bindet man in Published der eigenen Komponente ein Objekt einer eigenen Klasse ein um Eigenschaften im Objektinspektor als Untereinträge anzuzeigen (steht dann ein + davor). Diese Klasse ist von TPersistent abgeleitet.

Bsp:
Delphi-Quellcode:
type
  TMyNewPropertys = class(TPersistent)
  privat
    FFirstProperty : Boolean;
    FSecondProperty : String;
  published
    property FirstProperty : Boolean read FFirstProperty write FFirstProperty;
    property SecondProperty : Boolean read FSecondProperty write FSecondProperty;
  end;

....

  TMyComponent = class(TCustomControl)
  private
    FAdditionalPropertys : TMyNewPropertys;
...
  published
    property AdditonalPropertys : TMyNewPropertys read FAdditonalPropertys write FAdditonalPropertys;
...

constructor TMyComponent.Create(AOwner : TComponent);
begin
  ....
  FAdditionalPropertys := TMyNewPropertys.Create;
end;
Üblicherwereise benutzt mal für die Eigenschaften des Wrappers Getter- und Settermethoden um in MyComponent Eigenschaften anderer Klassen zu ändern. Ich empfehle dir mal unter dem Stichwort Wrapper zu suchen. Da gibt es sicher eine Menge zu in der DP.

Gruß oki

BAMatze 11. Mai 2009 08:23

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von Flips
Hi,

warum das Rad neu erfinden, such ma nach der Komponente TLabeledEdit.
lg, Flips

Hallo oki und Flips.

@TLabeledEdit: ist nicht exakt was ich meinte. Was ich brauche, ist eher sowas: Wenn die Komponente (habe ich wieder von TWinControl abgeleitet) nicht angewählt ist, soll sie ein Label zeigen, in der ein Wert drin steht. Wenn ich es anklicke, verschwindet das Label und das Edit wird sichtbar, damit ich den Wert ändern kann. Wenn ich wieder fertig ist, soll das Edit wieder verschwinden und das Label steht wieder an der Stelle. Brauche ich damit ich bei der schematischen Darstellung einer Technischen Zeichnung Werte Ändern kann.

@oki danke werde gleich mal schauen nach Wrapper.

Ps.: Falls es eine Standartkomponente gibt, dass das von mir beschrieben Verhalten aufweist, bitte sagen, kenne die noch nicht alle.

BAMatze

BAMatze 11. Mai 2009 08:48

Re: größe der Komponente automatisch anpassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
So hab hier mal mit den einfachsten Mitteln (um den Arbeitsaufwand möglichst gering zu halten) eine Komponente Vorbereitet, die zumindest zeigt, was ich möchte. Sie hat keinerlei Propertys oder irgendwas, was man sonst alles von Edit und Label gewohnt ist. Soll ja nur mal schmatisch sein.

Wie gesagt, weiß nicht ob es sowas gibt und wenn nein, möchte ich die Komponente für aus den oben genannten Gründen sozusagen in eine Komponente überführen, die ebend allen "gängigen" Ansprüchen genügt. Kenne diese Art von Komponete von einem Arbeitskollegen in C#. Die verwendet er auch relativ häufig.

oki 11. Mai 2009 09:18

Re: größe der Komponente automatisch anpassen
 
Hallo BAMatze,

das ist dann sicher doch etwas anderes wie das TLabeledEdit. Ich kenne persönlich keine Komponent, die diese Ansprüche erfüllt. Das muss aber nicht bedeuten, dass es keine gibt (zumindest ausserhalb der Standard-Delphi Componenten).

An deiner Stelle würde ich folgendermaßen umgehen:

- Ein eigenes Label von TCustomLabel ableiten,
- diesem Label ein Edit verpassen,
- das Edit ist ein privater Member der neuen Labelklasse,
- erhält das Label den Focus, wird das Edit darüber eingeblendet,
- verliert es den Focus, wird es wieder unsichtbar,
- alle Eigenschaften wie Font, Größe usw. erhält das Edit vom Label automatisch zugewiesen, so braucht man eigentlich auch keinen Wrapper.

Damit müsste das eigentlich so funzen. Ich bin mir nur nicht sicher, ob ein Label auch einen Focus bekommen kann. Muss ich noch mal schauen :gruebel:

Gruß oki

BAMatze 11. Mai 2009 09:25

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von oki
Hallo BAMatze,

Damit müsste das eigentlich so funzen. Ich bin mir nur nicht sicher, ob ein Label auch einen Focus bekommen kann. Muss ich noch mal schauen :gruebel:

Gruß oki

Also ein Label hat auf jeden Fall das onClick, mit dem ich das Edit hervorlocken :-D könnte und beim Edit kann man dann den Focus abfragen.
Was vieleicht interessant wäre, wenn man einprogrammieren könnte, ob "außerhalb" der Komponente geklickt wird. Das würde das mit dem Focus sicherlich nochmal vereinfachen, weil man dann auf ein Event reagieren könnte (nur mal so ne kleine Idee).

jfheins 11. Mai 2009 09:44

Re: größe der Komponente automatisch anpassen
 
Ich habe mal so eine Komponente gemacht - sie funktionierte im Grunde wie folgt:

Label und Edit erstellen, aber das Edit unsichtbar machen. (damit man nicht von außen alles verändern kann - was verändert werden soll, kann man ja wieder nach außen führen)

Beim Doppelklick aufs Label dem Edit den Text zuweisen (evtl. positionieren) und sichtbar machen

Wenn das Edit den Focus verliert oder Enter gedrückt wird, Label den text zuweisen und Edit unsichtbar machen

Wenn im Edit Esc gedrückt wird, Edit nur unsichtbar machen.


Ich denke die schwierigse Aufgabe ist es, das Edit so zu positionieren, dass der Text genau auf dem vom label zu liegen kommt. Könnte man vll. dadurch lösen, dass man die Mittelpunkte an die Gleiche Stelle rückt (ist aber nur so ne überlegung - in der Kompo die ich gemacht hab war die schriftgröße konstant)

BAMatze 11. Mai 2009 09:54

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von jfheins
Ich habe mal so eine Komponente gemacht - sie funktionierte im Grunde wie folgt:

Label und Edit erstellen, aber das Edit unsichtbar machen. (damit man nicht von außen alles verändern kann - was verändert werden soll, kann man ja wieder nach außen führen)

Beim Doppelklick aufs Label dem Edit den Text zuweisen (evtl. positionieren) und sichtbar machen

Wenn das Edit den Focus verliert oder Enter gedrückt wird, Label den text zuweisen und Edit unsichtbar machen

Wenn im Edit Esc gedrückt wird, Edit nur unsichtbar machen.


Ich denke die schwierigse Aufgabe ist es, das Edit so zu positionieren, dass der Text genau auf dem vom label zu liegen kommt. Könnte man vll. dadurch lösen, dass man die Mittelpunkte an die Gleiche Stelle rückt (ist aber nur so ne überlegung - in der Kompo die ich gemacht hab war die schriftgröße konstant)

Jap so funktioniert das kleine Programm, wie ich das oben mal gepostet habe. Label und Edit in einem TWinControl gepackt. Das TWinControl hat dort aber noch die feste Größe von 100 x 100 Pixel. Und noch hatte ich nix gefunden, wie man das eventuell ändern kann. Deswegen verfolge ich gerade oki´s Ansatz, das Edit in ein TCustomLabel zu integrieren.

Ps.: das Edit muss 3Pixel höher und 3 weiter nach links verschoben werden, dann liegen Schrift von Label und Edit genau übereinander (bei gleicher Textformatierung).

BAMatze 11. Mai 2009 10:58

Re: größe der Komponente automatisch anpassen
 
Hab hier warscheinlich wieder ein kleines Problem mit dem Parent (bin ja eigentlich schonmal froh, dass ich das verstanden hab :-D ).

Wenn ich das Edit in das TCustomLabel einbinde, dann muss ich ja eigentlich einen Parent wieder setzen, damit das Edit sichbar werden kann. Probiert habe ich nil und Self. Beide führen aber nicht dazu, dass das Edit sichbar wird. Wenn ich TLabEdit (ist der Name für die neue Komponente abgeleitet von TCustomLabel) einsetze, dann beschwert er sich, dass diese verschieden ist von TWinControl.
Welchen Parent sollte ich dort einsetzen?

jfheins 11. Mai 2009 11:20

Re: größe der Komponente automatisch anpassen
 
Du kannt ein TLabel nicht als Parent verwenden, weil es nicht von TWinControl abstammt.

Erstelle entweder eine komplett neue Kompo, abgeleitet von TWinControl oder verwende TStaticText als Vorfahr.

oki 11. Mai 2009 13:35

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von jfheins
Du kannt ein TLabel nicht als Parent verwenden, weil es nicht von TWinControl abstammt.

Erstelle entweder eine komplett neue Kompo, abgeleitet von TWinControl oder verwende TStaticText als Vorfahr.

Sorry, daran hatte ich nicht gedacht, verwende das TLabel zu selten. Somit gilt das was ich in Post #6 geschrieben habe, wobei du dann nicht von TCustomLable, sodern von TWinControl oder TCustomControl (verwende ich immer) ableiten musst. Dabei fällt dir dann aber die Aufgabe zu den Text auf deiner Komponente selber zu zeichnen. Halte ich aber eher für einen Vorteil. Verwendest du dein eigenes "Label" dann ausschließlich auf Rechner mit W2000 aufwärts, kannst du für die Ausgabe des Textes auch die GDI+ verwenden, wass die ganze Sache optisch dann mächtig aufwertet.

TStaticText nimmt dir natürlich den ganzen Text-Kram ab. Leite dann aber lieber von TCustomStaticText ab.

Gruß oki

BAMatze 11. Mai 2009 13:45

Re: größe der Komponente automatisch anpassen
 
Liste der Anhänge anzeigen (Anzahl: 1)
@oki ja hab schon alles umgestellt auf TWinControl, kein Thema. Hänge mal den aktuellen Status der Komponente an. Könnt ja mal Anregungen geben, wen es interessiert, bräuchte mal ein kleines Brainstorming, welche der normalen Propertys, außer alles was mit Fond ect. zusammenhängt, sinnvoll wäre wieder zu implizieren.

Edit: Datei angehängt

oki 11. Mai 2009 14:32

Re: größe der Komponente automatisch anpassen
 
Joop, geht doch gut vorwärts. Die Methode TTWinControlAnpassung würde ich ändern in ChangeEmbeddedEdit oder UpdateEditSize oder so. Ist zwar völlig wurscht, aber das Auge isst mit. Den alten Wert brauchst des Label brauchst du dir so eigentlich nicht merken. Der Wert als Solches reicht Vollständig. Verpass deinem neuen Label die Eigenschaft Text. Da steht dein einzutragender Wert drin. Beim Edit fängst du das Esc ab. Damit kannst du dann das Edit verstecken und änderst FText einfach nicht. Dan musst du aber sicher wieder ein Flag definieren, dass du setzt bevor du das Edit versteckst um es vom normalen "Lost Focus" zu unterscheiden wo ja der Wert geändert werden soll.

Eigenschaften für published ? ... nehm doch mal alle. Kenne eingentlich keine unnützen da.

Gruß oki

BAMatze 11. Mai 2009 15:04

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von oki
Joop, geht doch gut vorwärts. Die Methode TTWinControlAnpassung würde ich ändern in ChangeEmbeddedEdit oder UpdateEditSize oder so. Ist zwar völlig wurscht, aber das Auge isst mit.

Eigenschaften für published ? ... nehm doch mal alle. Kenne eingentlich keine unnützen da.

Gruß oki

Hmm ok hier erstmal das einfache, die Properties, die ich bisher identifiziert habe, die nützlich sind:
- Enabled
- Text
- Font(hier als Unterpunkte Color, Height, Name, Style)
- Visible
- eventuell Readonly (Wobei ich hier noch überlege, dann könnte man gleich einfach ein Label nehmen)
- Length
- MaxLength

Jetzt zu dem etwas schwierigeren Sachen, die ich auch teilweise noch nicht verstanden habe.

Zitat:

Zitat von oki
Den alten Wert brauchst des Label brauchst du dir so eigentlich nicht merken. Der Wert als Solches reicht Vollständig.

Hmm das verstehe ich so, dass ich meinen Quellcode etwa so abändern müsste:
Delphi-Quellcode:
procedure TLabEdit.FEdKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
// Die Änderung hier an dieser Prozedur sehen wie folgt aus: OnChange wird nur
// aktiviert, wenn eine Eingabe getätigt wurde, die verschieden von der vorherigen
// ist.
// Bei Esc wird alles wieder zurückgesetzt und das OnChangeEvent wird nicht aktiviert.
  if (Key = 13) then
    begin
      FEdEingabe.Visible := false;
      FLblAnzeige.Visible := true;
      FLblAnzeige.Caption := FEdEingabe.Text;
      if assigned(FOnChange) then FOnchange;
      ChangeEmbeddedEdit;
    end;
  if (key = 27) then
    begin
      FEdEingabe.Visible := false;
      FLblAnzeige.Visible := true;
      FEdEingabe.Text := sTextWert;
       ChangeEmbeddedEdit;
    end;
end;
Sollte ich, wenn ich die Prozedure so umschreibe immer noch ein Flag setzen? hab das mal so getestet und scheint erstmal wunderbar zu funktionieren.

Setter und Getter schreibe ich gerade direkt in die Komponente. Denke einen zusätzlichen TPresistent zu schreiben wäre aufwendiger. Vorallem wüsste ich da nur schwer, wie ich die Setter und Getter schreiben müsste. So erstelle ich mir eine Variable und dazu jeweils einen Setter und Getter plus einer Property in Published wo ich die Eigenschaft frei gebe.

oki 11. Mai 2009 15:33

Re: größe der Komponente automatisch anpassen
 
Hi,

erst mal sorry für den Verhaspler
Zitat:

Den alten Wert brauchst des Label brauchst du dir so eigentlich nicht merken.
Richtig interpretiert. Dabei musst du aber das Tastaturereignis des Edits abfangen, nicht des Labels (wenn du deine Methode FedKeyDown auf das OnKeyDown des Edits gesetzt hast, dann erübriegt sich mein Kommentar hierzu). Ansonsten hast du vollkommen recht, das Flag ist dabei überflüssig. Wie bin ich blos darauf gekommen :gruebel: . Na ich glaub ich war bei meinem vorherigen Post nicht ganz bei der Sache.

Ich würde auch noch das Exit des Edit abfangen. Das wird aus ausgelöst, wenn das Edit den Fokus verliert. z.B. man clickt neben das Edit wähend es aktiv ist. Da kannst du dann auch das Eingegebene übernehmen wie bei deinem "Enter" in KeyDown.

Letztes Thema; ich sehe bis jetzt immer noch keinen Ansatz wo du einen Wrapper brauchst. Mein Kommaentar in den vorherigen Posts zu diesem Thema war eher eine Vermutung incl. Erläuterung zu deiner Umschreibung mit TPersistent. Das du einen solchen brauchst wollte ich damit nicht ausdrücken. Wie gesagt, da du alle wichtigen Eigenschaften von deinem Label an das Edit übergeben kannst (Font, Left, Top ....) musst du eigentlich keine Eigenschaften des Edit veröffentlichen.

gruß oki

[edit] diverse Fehler wieder eingesammelt [/edit]

BAMatze 13. Mai 2009 09:10

Re: größe der Komponente automatisch anpassen
 
Hab nochmal versucht diese Funktion etwas zu verbessern:
Delphi-Quellcode:
procedure TLabEdit.FEdKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
// Die Änderung hier an dieser Prozedur sehen wie folgt aus: OnChange wird nur
// aktiviert, wenn eine Eingabe getätigt wurde, die verschieden von der vorherigen
// ist.
// Bei Esc wird alles wieder zurückgesetzt und das OnChangeEvent wird nicht aktiviert.
  if (Key = 13) then
    begin
      FEdEingabe.Visible := false;
      FLblAnzeige.Visible := true;
      FLblAnzeige.Caption := FEdEingabe.Text;
      if assigned(FOnChange) then FOnchange;
      ChangeEmbeddedEdit;
    end;
  if (key = 27) then
    begin
      FEdEingabe.Visible := false;
      FLblAnzeige.Visible := true;
      FEdEingabe.Text := sTextWert;
       ChangeEmbeddedEdit;
    end;
end;
Sieht jetzt wie folgt aus und scheint auch seine Schuldigkeit zu tun. Mir ist zumindest kein Fehler aufgefallen:

Delphi-Quellcode:
if key in [13, 27] then
     begin
      FEdEingabe.Visible := false;
      FLblAnzeige.Visible := true;
      case key of
      13: begin
            FsTextWert := FEdEingabe.Text;
            FLblAnzeige.Caption := FEdEingabe.Text;
            if assigned(FOnChange) then FOnchange;
          end;
      27: begin
            FEdEingabe.Text := FsTextWert;

          end;
      end;
    end
  else
    begin
      inherited;
      FLblAnzeige.Caption := FEdEingabe.Text;
      ChangeEmbeddedEdit;
    end;
Sieht so schöner aus.

Mache gleichmal einen extra Threat auf für das Problem, wie erkenne ich, dass außerhalb meiner Komponente geklickt wurde.

oki 13. Mai 2009 09:20

Re: größe der Komponente automatisch anpassen
 
Schöner ist Ansichtssache :lol:

Poste hier mal den Link zu deinem neuen Thread, dann brauch ich nicht suchen.

Gruß oki

BAMatze 13. Mai 2009 10:26

Re: größe der Komponente automatisch anpassen
 
Zitat:

Zitat von oki
Schöner ist Ansichtssache :lol:

Poste hier mal den Link zu deinem neuen Thread, dann brauch ich nicht suchen.

Gruß oki

hier der Link


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:41 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