Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Komponentenprogrammierung, DoExit und Font.Color


Jakane - Di 07.05.13 13:28
Titel: Komponentenprogrammierung, DoExit und Font.Color
Hallo liebe Delphi-Helfer :)

heut ist bei mir viel los ;)


Delphi-Quelltext
1:
2:
3:
  published
    { Objekteingenschaften }
    procedure DoExit; override;


Delphi-Quelltext
1:
2:
3:
4:
5:
procedure TJEdit.DoExit;
begin
  Font.Color:= clRed;
...
end;


Weiss jemand wieso meine Schrift beim Edit-Verlassen nicht rot wird? :)

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


WasWeißDennIch - Di 07.05.13 13:49

Ich verstehe Deinen Code nicht. Du hast DoExit überschrieben, richtig? Hast Du dann das inherited absichtlich weggelassen? Und wieso rufst Du reihenweise Funktionen auf, ohne mit dem Rückgabewert etwas anzufangen? Etwas verwirrend in meinen Augen.


Jakane - Di 07.05.13 14:08

Die nachfolgenden Funktionen waren auch unintressant, deswegen hab ich sie im Code mal rausgemacht.

Ändert aber nix das das die Schrift nicht rot wird :-/

inherited kenn ich nicht.
Im KeyPress hab ich es drin als Result für den Key aber ansonsten kann ich damit nichts anfangen. Und was ich nicht kenne lass ich nicht im Code.


WasWeißDennIch - Di 07.05.13 14:13

Das ist eine etwas merkwürdige Argumentation :). Versuch es mal so: verschieb DoExit nach protected (unbedingt das override so lassen), schreib als erste Zeile hinter das "begin" von DoExit ein "inherited;" (man kann es auch weglassen, sollte dann aber genau wissen, was man tut und entsprechende Gründe haben) und ändere die Schriftfarbe. Sollte das nicht genügen, kannst Du auch noch ein Repaint, Invalidate oder Update aufrufen, damit sich das Edit neu zeichnet.


Jakane - Di 07.05.13 14:40


Delphi-Quelltext
1:
2:
  protected
    procedure DoExit; override;


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TJEdit.DoExit;
begin
  inherited;
  Font.Color:= clRed;
//  Repaint;
//  Invalidate;
//  Update;
...
end;


Funktionieren alle 3 nicht :(

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


WasWeißDennIch - Di 07.05.13 14:47

Hast Du mal einen Breakpoint gesetzt? Wird der Code überhaupt ausgeführt? Welche Delphi-Version benutzt Du eigentlich? Bei mir hier unter XE funktioniert nämlich bislang alles so, wie ich es vorgeschlagen habe.


Jakane - Di 07.05.13 14:59


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:
unit JEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TSchreibrecht = (SRAlles, SRBuchstaben, SRGanzzahlen, SRDezimalzahlen,
                   SRDatum, SRZeit, SRDatumZeit, SRChr);

type
  TJEdit = class(TCustomEdit)
  private
    FSchreibrecht: TSchreibrecht;
    procedure SetSchreibrecht(Schreibrecht: TSchreibrecht);
    procedure SetReadOnly(RO: Boolean);
    function GetReadOnly: Boolean;
  protected
    { Protected-Deklarationen }
    procedure KeyPress(var Key: Char); override;
    procedure DoExit; override;
  public
    { Wärend der Programmierung auswählbare Funktionen }
  published
    { Objekteingenschaften }
    property Cursor;
    property Color;
    property Font;
    property Height;
//    property HelpContext; <- Störenfried verschwindet nicht ... -.-
    property Hint;
    property Left;
    property MaxLength;
    property Name;
    property SelStart;
    property TabStop;
    property Tag;
    property Text;
    property Top;
    property Visible;
    property Width;
    property ParentFont;
    property Schreibrecht: TSchreibrecht read FSchreibrecht write SetSchreibrecht;
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Jakane', [TJEdit]);
end;

procedure TJEdit.SetSchreibrecht(Schreibrecht: TSchreibrecht);
begin
  // Variable initialisieren
  if Text = Name then Text:= '';
  // Result
  FSchreibrecht:= Schreibrecht;
end;

function TJEdit.GetReadOnly: Boolean;
begin
  Result:= inherited ReadOnly;
end;

procedure TJEdit.SetReadOnly(RO: Boolean);
begin
  inherited ReadOnly:= RO;
  if RO then Color:= clRed;
  if not RO then Color:= clGreen;
end;

procedure TJEdit.DoExit;
begin
  inherited;
  Color:= clYellow;
  Repaint;
  Invalidate;
  Update;
  // Variable initialisieren
  if Trim(Text) = '' then EXIT;
  Text:= Trim(Text);
  // Schreibrecht SRZeit
  if FSchreibrecht = SRZeit then
  begin
    StrToTime(Text);
  end;
  // Schreibrecht SRDatum
  if FSchreibrecht = SRDatum then StrToDate(Text);
  // Schreibrecht SRDatumZeit
  if FSchreibrecht = SRDatumZeit then StrToDateTime(Text);
end;

procedure TJEdit.KeyPress(var Key: Char);
var
  sText : String;
  iSelStart : Integer;
begin
  // Variable initialisieren
  Color:= clBlack;
  sText:= Text;
  // Schreibrecht SRAlles
  if FSchreibrecht = SRAlles then
  begin
    Key:= Key;
  end;
  // Schreibrecht SRBuchstaben
  if FSchreibrecht = SRBuchstaben then
  begin
    if not (Pos(Key, 'abcdefghijklmnopqrstuvwxyzß ABCDEFGHIJKLMNOPQRSTUVWXYZ'#8) > 0then Key:= #0;
  end;
  // Schreibrecht SRGanzzahlen
  if FSchreibrecht = SRGanzzahlen then
  begin
    if Pos(Key, '-0123456789'#8) = 0 then Key:= #0;
  end;
  // Schreibrecht SRDezimalzahlen
  if FSchreibrecht = SRDezimalzahlen then
  begin
    // Zeichen-Änderung aber nur 1 Komma erlauben
    if Pos(Key, ';:,.-_ ') > 0 then
    begin
      Key:= ',';
      if Pos(Key, Text) > 0 then Key:= #0;
    end;
    if Pos(Key, '-1234567890,'#8) = 0 then Key:= #0;
  end;
  // Schreibrecht SRZeit
  if FSchreibrecht = SRZeit then
  begin
    if Pos(Key, ';:,.-_ ') > 0 then Key:= ':';
    if Pos(Key, '1234567890:'#8) = 0 then Key:= #0;
    // Formatierung
    // Wenn leer dann vorbelegen
    if Text = '' then
    begin
      Text:= TimeToStr(Now);
      SelStart:= 0;
    end;
    // Änderungen weitergeben
    iSelStart:= SelStart;
    if iSelStart in [25then iSelStart:= iSelStart + 1 else iSelStart:= iSelStart;
    Text:= Copy(Text, 1, iSelStart) + Copy(Text, iSelStart + 210);
    SelStart:= iSelStart;
  end;
  // Schreibrecht SRDatum
  if FSchreibrecht = SRDatum then
  begin
    if Pos(Key, ';:,.-_ ') > 0 then Key:= '.';
    if Pos(Key, '1234567890.'#8) = 0 then Key:= #0;
    // Formatierung
    // Wenn leer dann vorbelegen
    if Text = '' then
    begin
      Text:= DateToStr(Now);
      SelStart:= 0;
    end;
    // Änderungen weitergeben
    iSelStart:= SelStart;
    if iSelStart in [25then iSelStart:= iSelStart + 1 else iSelStart:= iSelStart;
    Text:= Copy(Text, 1, iSelStart) + Copy(Text, iSelStart + 212);
    SelStart:= iSelStart;
  end;
  // Schreibrecht SRDatumZeit
  if FSchreibrecht = SRDatumZeit then
  begin
    if Pos(Key, '1234567890.: '#8) = 0 then Key:= #0;
    // Formatierung
    // Wenn leer dann vorbelegen
    if Text = '' then
    begin
      Text:= DateTimeToStr(Now);
      SelStart:= 0;
    end;
    // Änderungen weitergeben
    iSelStart:= SelStart;       // 25.03.2013 12:05:35
    if iSelStart in [25101316then iSelStart:= iSelStart + 1 else iSelStart:= iSelStart;
    Text:= Copy(Text, 1, iSelStart) + Copy(Text, iSelStart + 222);
    SelStart:= iSelStart;
  end;
  // Schreibrecht SRChr
  if FSchreibrecht = SRChr then
  begin
    if Pos(Key, '1234567890'#8) = 0 then Key:= #0;
  end;
  // Result
  inherited KeyPress(Key);
end;

end.

Der Code wird durchgeführt. Aber irgendwie scheint das immer überschrieben zu werden.
In der Programmierzeit ist das Edit Grün, beim Programmstart ist das Edit aber Weiss.

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


WasWeißDennIch - Di 07.05.13 15:05

Hier noch einmal mein aktueller Stand:

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:
unit TestEdit;

interface

uses Classes, Controls, StdCtrls, Graphics;

type
  TTestEdit = class(TCustomEdit)
  private
    function GetReadOnly: Boolean;
    procedure SetReadOnly(const Value: Boolean);
  protected
    procedure DoExit; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
    property Text;
    property Visible;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TTestEdit]);
end;

{ TTestEdit }

constructor TTestEdit.Create(AOwner: TComponent);
begin
  inherited;
  ReadOnly := inherited ReadOnly;
end;

procedure TTestEdit.DoExit;
begin
  inherited;
  Font.Color := clRed;
end;

function TTestEdit.GetReadOnly: Boolean;
begin
  Result := inherited ReadOnly;
end;

procedure TTestEdit.SetReadOnly(const Value: Boolean);
begin
  inherited ReadOnly := Value;
  if Value then
    Color := clGray
  else
    Color := clWhite;
end;

end.

Das DoExit wird natürlich nur ausgeführt, wenn die Komponente den Fokus hatte und diesen nun abgibt. Ich sehe gerade, dass Delphi 5 in Deiner Signatur steht. Das kann ich leider erst nach Feierabend probieren, hier habe ich kein D5 zur Verfügung.


Jakane - Di 07.05.13 15:19


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TFHaupt.Button1Click(Sender: TObject);
begin
  if JEdit1.Color = clYellow then ShowMessage('Gelb');
  if JEdit1.Color = clBlack then ShowMessage('Schwarz');
  if JEdit1.Color = clRed then ShowMessage('Rot');
  if JEdit1.Color = clWindow then ShowMessage('Weiss');
  if JEdit1.Color = clGreen then ShowMessage('Grün');
end;


ShowMessage gibt Grün aus, aber das Edit sieht Weiss aus

Moderiert von user profile iconMartok: Code- durch Delphi-Tags ersetzt


WasWeißDennIch - Di 07.05.13 15:24

Wenn Du Dich bis ca. 18:00 Uhr gedulden kannst, probiere ich das auch mal mit Delphi 5.


Jakane - Di 07.05.13 15:29

Ok, bin 18Uhr + - da


WasWeißDennIch - Di 07.05.13 18:11

So, hier mal mein Teststand mit Delphi 5.


Jakane - Di 07.05.13 18:52

Ich habe den Code 1:1 ersetzt, compiliert und die Komponente dann neu in meine Test-Exe eingefügt.

Die Schrift wird nicht rot :(
aber das Text:= 'AAAAA'; das ich davor eingefügt habe wird gemacht

Langsam finde ich das seltsam


WasWeißDennIch - Di 07.05.13 19:10

Bei mir wird sie rot, sowohl mit dem XE-Kompilat unter Vista 32 als auch mit dem D5-Kompilat unter Win8 64. Sehr merkwürdig. Hast Du das Package mal komplett entfernt und neu erzeugt?


Jakane - Di 07.05.13 19:14

ich weiss nicht wie man komponenten löscht


WasWeißDennIch - Di 07.05.13 19:32

Unter "Komponenten - Packages" das entsprechende abhaken, dann am Besten in das enthaltende Verzeichnis gehen und die *.bpl löschen. Anschließend das Package neu schnüren und installieren.


Jakane - Di 07.05.13 19:33

Hab ich gemacht.
In meiner Test-Exe hat das nicht geholfen, auch das Löschen aus der Uses und neu einsetzen nicht.
Aber in einem komplett frischen Projekt funktionierts...

Ich hasse mein Delphi -.-

Ich werd also meine Text-Exe morgen neu schreiben ^^


Blawen - Di 07.05.13 23:22

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
In meiner Test-Exe hat das nicht geholfen, auch das Löschen aus der Uses und neu einsetzen nicht.
Aber in einem komplett frischen Projekt funktionierts...
So ins Blauen geraten, würde ich vermuten, dass Du auch selber zeichnest?


Jakane - Mi 08.05.13 10:01

user profile iconBlawen hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
In meiner Test-Exe hat das nicht geholfen, auch das Löschen aus der Uses und neu einsetzen nicht.
Aber in einem komplett frischen Projekt funktionierts...
So ins Blauen geraten, würde ich vermuten, dass Du auch selber zeichnest?


Bisher zeichne ich gar nichts, das würde erst für mich viel später kommen das zu lernen.
Aber da ich das noch nicht kenne, wie krieg ichs raus ob ich zeichne oder mein Delphi zickt?


Jakane - Mi 08.05.13 11:00

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe den Code 1:1 ersetzt, compiliert und die Komponente dann neu in meine Test-Exe eingefügt.

Die Schrift wird nicht rot :(
aber das Text:= 'AAAAA'; das ich davor eingefügt habe wird gemacht

Langsam finde ich das seltsam


Ich habe eben beim Test festgestellt, das die Komponente problemlos funktioniert, wenn das Formular fsNormal ist.
Meine Test-Exe ist aber eine MDI-Form, da funktioniert das nicht.

Kann man das irgendwie einstellen?

Und der ist schuld! glaub ich xD

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TCustomForm.SetFormStyle(Value: TFormStyle);
var
  OldStyle: TFormStyle;
begin
  if FFormStyle <> Value then
  begin
    if (Value = fsMDIChild) and (Position = poDesigned) then
      Position := poDefault;
    if not (csDesigning in ComponentState) then DestroyHandle;
    OldStyle := FFormStyle;
    FFormStyle := Value;
    if ((Value = fsMDIForm) or (OldStyle = fsMDIForm)) and not Ctl3d then
      Color := NormalColor;
    if not (csDesigning in ComponentState) then UpdateControlState;
    if Value = fsMDIChild then Visible := True;
  end;
end;


WasWeißDennIch - Mi 08.05.13 11:08

Das Edit verhält sich unterschiedlich je nach Art des Formulars? Dafür habe ich ad hoc keine Erklärung, das müsste ich mal unter Delphi 5 versuchen nachzuvollziehen. Kann aber dauern.


WasWeißDennIch - Mi 08.05.13 11:25

Zwischenstand: unter Delphi 2007 funktioniert alles auch auf einem MDI-Child, soweit ich bislang feststellen kann.


Jakane - Mi 08.05.13 11:34

Hab aber kein D7, bin froh ein D5 zu haben ^^
jemand anderes eine Idee, oder eine andere Lösung?


WasWeißDennIch - Mi 08.05.13 11:55

Häng doch das Problemprojekt (*.dpr, *.pas und *.dfm genügen) mal an, dann kann ich zu Hause mal unter Delphi 5 nachsehen, woran es liegen könnte.


Jakane - Mi 08.05.13 12:56

Habe grade eine Lösung gefunden.
NUR das Hauptformular als MDIForm macht Ärger.
Andere Formular (MDIChild) und Panel werden davon nicht betroffen und machen was sie sollen :)

Das Projekt ist deine Komponente und ein Blank-Projekt ^^

War aber ein großer Weg das rauszukriegen.


WasWeißDennIch - Mi 08.05.13 13:00

Ein MDI-Form ist ja auch nicht dazu gedacht, Controls aufzunehmen (ein Hauptmenü mal ausgenommen). Dafür gibt es die MDI-Children. Wobei MDI ja seit Window 95 eigentlich als "out" gilt, man sollte also gute Gründe haben, MDI zu verwenden (es gibt solche durchaus, nicht falsch verstehen).


Jakane - Mi 08.05.13 15:34

Wieso gilt MDI als out?
Ich find das toll. (ist das schon ein Grund? :D )