Autor Beitrag
KleinesPferd
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 22.02.11 12:14 
Hallöchen,

Ich bin ziemlich frisch hier im Forum, deswegen bitte ich um eine Woche Nachsicht, bis ich mich hier im Forum an die richtigen Stellen vorgearbeitet habe.

Kurze Randbedingung: Win XP und D7 Enterprise


Es gibt eine Komponenten namens LabelEdit, die allerdings auf TEdit basiert.
Ich benötige jetzt ein paar Schubser in die andere Richtung, da ich ein LabelEdit erstellen möchte, oder auch benutzen möchte, dass:

* Label als Main (sodass durch die Events onMouseEnter/Leave bestehen bleiben (-> um Label wie links zu handhaben))
* Label OnClick, soll dann ein Edit anzeigen, dass so breit, hoch und beschriftet ist, wie das Label, und wenn dann das Edit verlassen/Enter gedrückt wird, der neue Wert dem Label als caption übergeben wird.
* Edit ohne 3D Effekt, nur reines Feld, mit selber Schrift wie Label und Größe, und anpassbarem Hintergrund, ist.

Bisher habe ich dies mit vielen Labels und Einer Editbox gelöst und, die jedesmal beim OnClick-Event an die entsprechende Position geschoben und auch die Rückgabe hat wunderbar funktioniert. Ist nur leider ziemlich statisch.

Jetzt möchte ich diese Funktionalität in einem anderen Projekt nutzen, aber diesen Aufwand reduzieren.

Wie ich eine Komponente erstelle und weitere Eigenschaften hinzufüge, wird in guten Tutorials erklärt, aber für mein Problemchen, fand ich noch nichts und ich suche nun eine quasi "selbstentwickelte" Lösung.
Könnte mir dabei jemand unter die Arme greifen?

Viele Grüße


Moderiert von user profile iconGausi: Topic aus VisualCLX (Component Library for Cross Platform) verschoben am Di 22.02.2011 um 11:15
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: Di 22.02.11 12:29 
Versuche mal, Deine Vorgaben nachzuvollziehen:
1. Soll das Label und nicht das Editfeld den Focus erhalten und dann Tastaturabfragen verwalten. Was aber schwierig ist, wenn Du in das Edit-Feld etwas einträgst. Denn dann hat dieses den Focus und verwaltet die Tastatureingaben
2. Beim Verlassen des Editfeldes soll das Caption des Labels den Inhalt des Editfeldes bekommen.

Frage: Soll das Editfeld immer angezeigt werden, oder nur, wenn Du dem Label den Focus erteilst, sozusagen auf Abruf?

_________________
Toleranz ist eine Grundvoraussetzung für das Leben.
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 22.02.11 12:38 
Also ich würds mal so probieren:

Du machst ne neue Klasse, abgeleitet von TLabel. Diesem fügst du per Delegation (also unter private) ein Edit hinzu. Dieses wird beim constructor erstellt und unsichtbar gemacht. Klickst du auf das Label (OnClick), dann schaltest du das Label unsichtbar und das Edit sichtbar. Bist du fertig, machst du das Edit wieder unsichtbar und zeigst das Label wieder an.

Das Edit kannst du ja so konfigurieren, dass es ohne 3D-Effekt ist.

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 22.02.11 12:43 
user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
Versuche mal, Deine Vorgaben nachzuvollziehen:
1. Soll das Label und nicht das Editfeld den Focus erhalten und dann Tastaturabfragen verwalten. Was aber schwierig ist, wenn Du in das Edit-Feld etwas einträgst. Denn dann hat dieses den Focus und verwaltet die Tastatureingaben
2. Beim Verlassen des Editfeldes soll das Caption des Labels den Inhalt des Editfeldes bekommen.

Frage: Soll das Editfeld immer angezeigt werden, oder nur, wenn Du dem Label den Focus erteilst, sozusagen auf Abruf?


Zum groben Gebrauch:

Durchs Maus-übers-Label-fahren soll das Label definierbar optisch hervorgehoben werden. Beispielsweise wie die Links im Browser. Wenn ich dann allerdings auf das Label klicke, wünsche ich mir, dass ich es editieren kann. Somit würde der Focus und die Tastatureingabe wirklich aufs Edit Feld übergehen. Beim Verlassen des Edt Feldes oder beim Drücken von Enter, oder bspw Pfeiltasten , soll dann der geänderte Text dem Label als Caption übergeben werden um somit eine Textänderung vorzunehmen und evtl die nächste 'Textstelle' angesprungen werden können. Und wenn der Text dann beim Label angekommen ist, kann das Editfeld wieder im Hintergrund versinken.

Das Editfeld soll ja nur dann angezeigt werden, wenn der Text aktiv vom Nutzer geändert wird.

Zu meiner Motivation: Bisher war es immer leichter ein Label optisch hervorzuheben, auch hatte es den Vorteil, einen Transparenten Hintergrund zu haben, sodass ich den Text vor einen Gradienten oder über Bilder/Grafiken legen konnte. Dies ist mir bei Editboxen bisher noch nicht gelungen. Auch störte mich da die Änderung des Cursors. Nun möchte ich aber noch die Annehmlichkeit der 'Veränderbarkeit' in das Label übernehmen.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

user profile iconXion hat folgendes geschrieben Zum zitierten Posting springen:
Also ich würds mal so probieren:

Du machst ne neue Klasse, abgeleitet von TLabel. Diesem fügst du per Delegation (also unter private) ein Edit hinzu. Dieses wird beim constructor erstellt und unsichtbar gemacht. Klickst du auf das Label (OnClick), dann schaltest du das Label unsichtbar und das Edit sichtbar. Bist du fertig, machst du das Edit wieder unsichtbar und zeigst das Label wieder an.

Das Edit kannst du ja so konfigurieren, dass es ohne 3D-Effekt ist.


So werde ich das mal angehen. Hoffe es geht so leicht ;)
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 22.02.11 12:58 
Joa, das geht schon. Bei Problemen einfach nochmal fragen.

PS: Es ist nicht nötig den kompletten Text nochmal zu zitieren :D
Schreib einfach @Xion und @Tranx, dann ist alles klar :mrgreen:

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 22.02.11 14:38 
So, ich hab mir ein TBoundEdit erstellt, dazu ein CustonLabelEdit und am Ende fasse ich dies alles in der LabelEdit zusammen. Das ganze sehr stark an die ExtCtrls angelehnt.

Jetzt wird mir ein Label unter Beispiele hinzugefügt, dieses hat auch einen Eintrag, Editbox, aber der ist grau und leer.

Wie kann ich denn hier so schön Quelltext einfügen? Wäre wohl einfacher um zu sehen, wo mein Fehler liegt...

Ich glaube ich denke zu kompliziert... :oops:
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 22.02.11 14:41 
ausblenden Quelltext
1:
<span class="inlineSyntax"><span class="codecomment">{PROTECTTAG771fc3749066f1df9be07aaa82d27631}</span></span>					


Das was du machst hört sich irgendwie zu kompliziert an :D

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 22.02.11 14:50 
Dann füge ich mal meinen überwältigenden Code ein

Hab mir auch zuerst gedacht, neues Label erstellen, Verweis auf Edit hinzufügen und über label.labeledit.text das ansprechen, aber sooo weit bin ich noch ned.

Grüße


In dieser Ansicht schauts sogar übersichtlicher aus. Und so hab ich den ersten Fehler schon gefunden. TCustomLabelEdit.create muss irgendwie anders ausschauen ;)


[update]
Es wird langsam was .....


Zuletzt bearbeitet von KleinesPferd am Mi 23.02.11 10:38, insgesamt 1-mal bearbeitet
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
Beiträge: 1952
Erhaltene Danke: 128

Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
BeitragVerfasst: Di 22.02.11 15:08 
Hui...
kommt mir extrem "ordentlich" vor. Keine Ahnung ob das nun gut oder schlecht ist :P

Ich hätts eher so gemacht:

ausblenden volle Höhe 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:
  type TEditableLabelItem=(elLabel, elEdit);
  type TEditableLabelClickEvent = procedure( Item: TEditableLabelItem ) of object;
  type TEditableLabel=class(TLabel)
    private
      Edit: TEdit;
      VOnClick: TEditableLabelClickEvent ;

      procedure LabelClick(Sender: TObject);
      procedure EditClick(Sender: TObject);
    public
      constructor Create(AOwner: TWinControl); override;

      property OnClick: TEditableLabelClickEvent read VOnClick write VOnClick;
  end;

constructor TEditableLabel.Create(AOwner: TWinControl);
begin
  inherited Create(AOwner);
  Self.OnClick:=LabelClick;

  Edit:=TEdit.Create(AOwner);
  Edit.Parent:=AOwner;
  //Edit Style ändern
  Edit.Visible:=False;
  Edit.OnClick:=EditClick;
end;

procedure TEditableLabel.LabelClick(Sender: TObject);
begin
  Edit.Text:=Self.Caption;
  Edit.Visible:=True;
  Self.Visible:=False;
  if Assigned(VOnClick) then
    VOnClick(elLabel);
end;

procedure TEditableLabel.EditClick(Sender: TObject);
begin
  if Assigned(VOnClick) then
    VOnClick(elEdit);
end;

[...]


//Edit:
Ja, das mit dem Edit als property von dir ist eigentlich ganz hübsch

_________________
a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Di 22.02.11 16:09 
Kleines Update:

Erstellen der Komponenten funktioniert. Label UND Editbox erscheinen. Momentan ist die Editbox noch bei (0,0) fix, aber das kommt dann morgen.
Desweiteren werde ich die Komponenten nicht vom Label ableiten, sondern von TCombopent, sodass es ein BoundLabel und ein BoundEdit gibt, da ich so beim editieren, das Label invisible schalten kann, was momentan ein komplettes Verschwinden hervorruft.

Ausserdem lassen sich dann so, die Eigenschaften rausführen, die ich direkt benötigen wollen würde.
Dazu aber morgen mehr.

Vielen Dank bisher
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Mi 23.02.11 01:08 
Meine bisherige Arbeit,

Sobald ich nun etwas im OI an den Label oder Edits ändern möchte, kommt eine Fehlermeldung, Stapelüberlauf, starten sie Delphi neu.
Ich hoffe, dies regelt sich, sobald ich die Left/Top Werte von TMyLabelEdit = class (TWinControl) an die TMyBoundEdit/Label weiterreiche und somit diese Punkte bei den MyBounds ausblenden kann.
Wie ich dies anstelle, weiss ich aber noch nicht. Für Vorschläge bin ich offen.

Guts Nächtle

Edit:
* inherited ist drin,
* werde mich daran halten, den quelltext nur einmal einzufügen und den immer wieder auf den neuesten stand bringen,
* ein problem ist aufgetaucht, sobald ich das neue LabelEdit auf eine Form setze, die Form dann schliesse, kommt eine Fehlermeldung, "Zugriffsverletzung an Adresse 00000000, Fehler beim Lesen von Adr. 00000000". DelphiFehler "Zugriffsverletzung bei Adresse 0083B551 in Modul vcl70.bpl. Lesen von Adresse 00000370."


Zuletzt bearbeitet von KleinesPferd am Mi 23.02.11 10:52, insgesamt 3-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 23.02.11 06:40 
user profile iconKleinesPferd hat folgendes geschrieben Zum zitierten Posting springen:
Sobald ich nun etwas im OI an den Label oder Edits ändern möchte, kommt eine Fehlermeldung, Stapelüberlauf, starten sie Delphi neu.
Du hast bei der Zuweisung an top in SetTop usw. das inherited vergessen. ;-)
KleinesPferd Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 29



BeitragVerfasst: Mi 23.02.11 10:42 
ausblenden volle Höhe 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:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
unit MyControls;

interface

uses
SysUtils,Classes,ExtCtrls,Controls,StdCtrls;

type

  TMyBoundEdit = class (TEdit)
   private
    { Private-Deklarationen }
     function GetLeft :Integer;
     function GetTop  :Integer;
     procedure SetLeft(const Value: Integer);
     procedure SetTop(const Value: Integer);
     procedure SetHeight(const Value: Integer);
     procedure SetWidth(const Value: Integer);

  protected
    { Protected-Deklarationen }
  public
    constructor Create(AOwner: TComponent); override;
    { Public-Deklarationen }
  published
    property Top: Integer read GetTop write SetTop;
    property Left: Integer read GetLeft write SetLeft;
    { Published-Deklarationen }

end;

TMyBoundLabel = class (TLabel)
  private
    { Private-Deklarationen }
     function GetLeft :Integer;
     function GetTop  :Integer;
     procedure SetLeft(const Value: Integer);
     procedure SetTop(const Value: Integer);
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
      constructor Create(AOwner: TComponent); override;
  published
    property Top: Integer read GetTop write SetTop;
    property Left: Integer read GetLeft write SetLeft;
    { Published-Deklarationen }
  end;

TMyLabelEdit = class (TWinControl)
  private
    { Private-Deklarationen }
    FMyEdit:TMyBoundEdit;
    FMyLabel:TMyBoundLabel;
  protected
    { Protected-Deklarationen }
    procedure SetParent(AParent: TWinControl); override;
//    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure SetName(const Value: TComponentName); override;
  public
    { Public-Deklarationen }
      constructor Create(AOwner: TComponent); override;
//      destructor Destroy(AOwner: TComponent); override;
  published
      property MyEdit: TMyBoundEdit read FMyEdit ;
      property MyLabel: TMyBoundLabel read FMyLabel ;
    { Published-Deklarationen }
  end;


procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('My Controls', [TMyLabelEdit]);
end;

constructor TMyBoundEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Name := 'SubEdit';  { do not localize }
  SetSubComponent(True);
  if Assigned(AOwner) then
    Text :=  AOwner.Name;
end;

procedure TMyBoundEdit.SetHeight(const Value: Integer);
begin
inherited height:= Value;
end;

procedure TMyBoundEdit.SetWidth(const Value: Integer);
begin
inherited width:= Value;
end;

procedure TMyBoundEdit.SetTop(const Value: Integer);
begin
inherited top:= Value;
end;

procedure TMyBoundEdit.SetLeft(const Value: Integer);
begin
inherited left:=Value;
end;

function TMyBoundEdit.GetTop  :Integer;
begin
Result := inherited Top;
end;

function TMyBoundEdit.GetLeft  :Integer;
begin
Result := inherited Left;
end;

constructor TMyBoundLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Name := 'SubLabel';  { do not localize }
  SetSubComponent(True);
  if Assigned(AOwner) then
    Caption :=  AOwner.Name;
end;

function TMyBoundLabel.GetTop  :Integer;
begin
Result := inherited Top;
end;

function TMyBoundLabel.GetLeft  :Integer;
begin
Result := inherited Left;
end;

procedure TMyBoundLabel.SetTop(const Value: Integer);
begin
inherited top:= Value;
end;

procedure TMyBoundLabel.SetLeft(const Value: Integer);
begin
inherited left:=Value;
end;

constructor TMyLabelEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  if Assigned(FMyLabel) then exit;
  FMyLabel := TMyBoundLabel.Create(Self);
  FMyLabel.FreeNotification(Self);

  if Assigned(FMyEdit) then exit;
  FMyEdit := TMyBoundEdit.Create(Self);
  FMyEdit.FreeNotification(Self);
end;

{procedure TMyLabelEdit.Notification(AComponent: TComponent;
  Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (AComponent = FMyLabel) and (Operation = opRemove) then
    FMyLabel := nil;
end;         }


procedure TMyLabelEdit.SetName(const Value: TComponentName);
begin
  if (csDesigning in ComponentState) and ((FMyLabel.GetTextLen = 0or
     (CompareText(FMyLabel.Caption, Name) = 0)) then
    begin
      FMyLabel.Caption := Value;
      FMyEdit.Text  := Value;
    end;
  inherited SetName(Value);
end;

procedure TMyLabelEdit.SetParent(AParent: TWinControl);
begin
  inherited SetParent(AParent);
  if FMyEdit = nil then exit;
  FMyEdit.Parent := AParent;
  FMyEdit.Visible := True;

  if FMyLabel = nil then exit;
  FMyLabel.Parent := AParent;
  FMyLabel.Visible := True;
end;

initialization

finalization


end.