![]() |
TCheckBox TComboBox laufzeitgeneriert - Eigenschaften setzen
Hallo!
Ich habe folgendes Problem und hoffe auf Hilfe durch einen anderen Programmier-Freak. Während des Programmlaufes werden in einer TGroupBox unterschiedliche viele TCheckBox und TComboBox erzeugt. Name, Position und Caption werden entsprechend der Anzahl automatisch berechnet bzw. aus einer Datenbank entnommen. Jede TCheckBox kann bei onclick bzw. jede TComboBox bei onchange mit
Delphi-Quellcode:
ausgewertet werden.
procedure TForm.ChgCB(Sender: TObject);
var s : string; varBool : Boolean; varText : string; begin .... s := Self.ActiveControl.Name; if (FindComponent(s) is TCheckBox) then varBool := (TCheckBox(FindComponent(s)).checked); if (FindComponent(s) is TComboBox) then varText := (TComboBox(FindComponent(s)).Text); .... end; Jedoch sind alle meine Versuche, Checked während des Programmlaufes einen Wert zuzuweisen mißlungen. Die Variante:
Delphi-Quellcode:
läßt sich nicht compilieren. Folgender Fehler wird angezeigt:
s := Self.ActiveControl.Name;
if (FindComponent(s) is TCheckBox) then (TCheckBox(FindComponent(s)).checked) := varBool; if (FindComponent(s) is TComboBox) then (TComboBox(FindComponent(s)).Text) := varText; Der linken Seite kann nichts zugewiesen werden. Sollte jemand die Lösung kennen, so bitte ich um den noch fehlenden Tipp. Eddy [edit=Sakura]Überschrift geändert, DELPHI-Tags gesetzt[/edit] |
Zitat:
1. unnötig 2. in diesem Zusammenhang ungültig. |
Du kannst direkt über den Sender gehen. Ist eleganter und einfacher:
Delphi-Quellcode:
procedure TForm.ChgCB(Sender: TObject);
var varBool : Boolean; varText : string; begin .... if Sender is TCheckBox then varBool := TCheckBox(Sender).Checked else if Sender is TComboBox then varText := (TComboBox(Sender).Text); .... // später dann if Sender is TCheckBox then TCheckBox(Sender).Checked := varBool; if Sender is TComboBox then TComboBox(Sender).Text := varText; end; |
Sehr geehrter Sakura,
Hallo jbg, superschnelle Antworten - hätte ich gar nicht gedacht. Ich bin begeistert!!! Vielleicht hätte ich doch etwas mehr schreiben sollen, aber ich wollte es mit den Erläuterungen auch nicht übertreiben. Die Hälfte Deines Vorschlages funktioniert und macht den Quelltext schlanker. Ich habe die ursprüngliche Variante als Kommentar zwecks Vergleich stehen lassen. Beim Setzen des gewünschten Wertes kann ich Deinen Vorschlag nicht benutzen, da die zu ändernde Komponente nicht direkt angesprochen wird. Zwecks besseren Verständnis habe ich die beiden Routinen mal komplett hinterlegt.
Delphi-Quellcode:
Ich hoffe, Du hast noch eine Idee.
{Ereignisbehandlung für TCheckBox.onclick / TComboBox.onchange }
procedure TFKasse.ChgAdrZK(Sender: TObject); var adrid : integer; s : string; begin {öffnet die Datenbank (DB) in der die ZK = Zusatzkriterien gespeichert werden sollen} UP_DBActiv(TabAdrZK, SessN, DataPath, fnAdrZK); {öffnet die Datenbank} {TabAdr steht für eine Adress-DB, AdrID sorgt für die eineindeutige Identifizierung einer gewälten Adresse} adrid := TabAdr.FieldByName('AdrID').AsInteger; {es werden nur die ZK der aktuellen Adresse gefiltert (falls vorhanden) } SetFilter(TabAdrZK, 'AdrID='+IntToStr(adrid)); {liefert cb<nr> oder cbx<nr> zurück, wobei die nr beim Erzeugen eines ZK automatisch generiert wurde } s := Self.ActiveControl.Name; {wenn es ein gespeichertes ZK gibt, muß sich der Name von TCheckBox oder TComboBox in einem Feld cbName finden lassen} // an jbg: ich weiß, das begin und end an dieser Stelle überflüssig sind { wenn gefunden, dann nur Eigenschaft Checked oder Text ändern} if TabAdrZK.Locate('cbName', s, []) then begin TabAdrZK.Edit; end { wenn nicht, dann der DB hinzufügen und dann Eigenschaften speichern} else begin TabAdrZK.Insert; TabAdrZK.FieldByName('AdrID').AsInteger := adrid; TabAdrZK.FieldByName('cbName').AsString := s; end; { hier funktioniert die von skura vorgeschlagene Variante} // if (FindComponent(s) is TCheckBox) // then TabAdrZK.FieldByName('Checked').AsBoolean := (TCheckBox(FindComponent(s)).checked); if (Sender is TCheckBox) then TabAdrZK.FieldByName('Checked').AsBoolean := TCheckBox(Sender).Checked; // if (FindComponent(s) is TComboBox) // then TabAdrZK.FieldByName('Text').AsString := (TComboBox(FindComponent(s)).Text); if (Sender is TComboBox) then TabAdrZK.FieldByName('Text').AsString := TComboBox(Sender).Text; TabAdrZK.Post; end; { beim Wechsel der Adreßdatei müssen die ZusatzKriterien aus TabAdrZK für die jeweilige Adresse (aus bereits geöffneter DB TabAdr) geladen werden; für Testzwecke über einen SpeedButton realisiert } procedure TFKasse.sbLoadAdrZKClick(Sender: TObject); var adrid : integer; handle : HWND; bValue : boolean; s, sValue : string; // str : array[0..255] of char; // comp : TComponent; begin UP_DBActiv(TabAdrZK, SessN, DataPath, fnAdrZK); adrid := TabAdr.FieldByName('AdrID').AsInteger; SetFilter(TabAdrZK, 'AdrID='+IntToStr(adrid)); TabAdrZK.First; while not TabAdrZK.Eof do begin { Name einer geänderten Komponente aus DB holen; wurde für die akt. Adresse aus TabAdr bei Änderung gespeichert sollte keine Änderung durch Nutzer vorgenommen worden sein, steht der Name der Komponente auch nicht in TabAdrZK } s := TabAdrZK.FieldByName('cbName').AsString; handle := TCheckBox(FindComponent(s)).Handle; if (FindComponent(s) is TCheckBox) then begin bValue := TabAdrZK.FieldByName('Checked').AsBoolean; { hier der Vorschlag von sakura Ergebnis: der then-Zweig wird nicht angesprungen, weil der Sender vom Typ TSpeedButton ist } if Sender is TCheckBox then TCheckBox(Sender).Checked := bValue; end; if (FindComponent(s) is TComboBox) then begin sValue:= (TabAdrZK.FieldByName('Text').AsString); { das gleiche Erg. wie oben } if Sender is TComboBox then TComboBox(Sender).Text := sValue; end; TabAdrZK.Next; end; end; mfg eddy PS: wie kriegt man die Formatierung des Quelltextes zwischen
Code:
hin ?
und
[edit=Sakura]CODE-Tags in DELPHI-Tags umbenannt. Deine Antwort :)[/edit] |
Hallo Sakura,
ich habe mein oben beschriebenes Problem lösen können. Auf einer Delphi-Seite habe ich im Zusammenhang mit CheckBox eine Befehlsfolge der Art:
Delphi-Quellcode:
gefunden. Über Hilfetexte war dann der Weg zu BM_SETCHECK nicht mehr sehr weit. Ich bin zwar noch ein Stückchen weit weg davon, alle komplett zu verstehen, aber der Anfang ist gemacht.
SendMessage(handle, BM_GETCHECK, ....);
Für den Fall, daß ein anderer Suchender ein ähnliches Problem hat, hänge ich die funktionsfähige Lösung mal noch hinten an.
Delphi-Quellcode:
Zur Vervollständigung noch die Prozedur zum Löschen der Werte, wenn
{ beim Wechsel der Adreßdatei müssen die ZusatzKriterien aus TabAdrZK
für die jeweilige Adresse (aus bereits geöffneter DB TabAdr) geladen werden; für Testzwecke über einen SpeedButton realisiert } procedure TFKasse.sbLoadAdrZKClick(Sender: TObject); var adrid : integer; handle : HWND; bValue : boolean; s, sValue : string; begin if pcAdr1.ActivePage = tsZK then begin sbClrZKClick(Sender); UP_DBActiv(TabAdrZK, SessN, DataPath, fnAdrZK); adrid := TabAdr.FieldByName('AdrID').AsInteger; SetFilter(TabAdrZK, 'AdrID='+IntToStr(adrid)); TabAdrZK.First; while not TabAdrZK.Eof do begin { Name einer geänderten Komponente aus DB holen; wurde für die akt. Adresse aus TabAdr bei Änderung gespeichert sollte keine Änderung durch Nutzer vorgenommen worden sein, steht der Name der Komponente auch nicht in TabAdrZK } //cb steht sowohl für CheckBox als auch ComboBox s := TabAdrZK.FieldByName('cbName').AsString; if (gbEinzel.FindComponent(s) is TCheckBox) then begin bValue := TabAdrZK.FieldByName('Checked').AsBoolean; handle := TCheckBox(gbEinzel.FindComponent(s)).Handle; SendMessage(handle, BM_SETCHECK, Integer(bValue), 0); end; if (gbGruppen.FindComponent(s) is TComboBox) then begin sValue:= (TabAdrZK.FieldByName('Text').AsString); handle := TComboBox(gbGruppen.FindComponent(s)).Handle; SendMessage(handle, WM_SETTEXT, 0, integer((sValue))); end; TabAdrZK.Next; end; end; end; von einem Datensatz zum nächsten gewechselt wird:
Delphi-Quellcode:
Vielleicht nützt ja eine meiner Programmzeilen mal jemand anderen, Probleme zu lösen.
procedure TFKasse.sbClrZKClick(Sender: TObject);
var i : integer; Handle : HWND; s, sValue : string; begin for i := 0 to gbEinzel.ComponentCount-1 do begin s := gbEinzel.Components[i].Name; if (gbEinzel.FindComponent(s) is TCheckBox) then begin Handle := TCheckBox(gbEinzel.FindComponent(s)).Handle; SendMessage(Handle, BM_SETCHECK, Integer(false), 0); end; end; for i := 0 to gbGruppen.ComponentCount-1 do begin s := gbGruppen.Components[i].Name; if (gbGruppen.FindComponent(s) is TComboBox) then begin sValue := ''; Handle := TCheckBox(gbGruppen.FindComponent(s)).Handle; SendMessage(Handle, WM_SETTEXT, 0, integer((sValue))); end; end; end; 8) I'am happy!! so long eddy |
Moin eddy,
ich hoffe Du hast nicht allzulange nach BM_SETCHECK woanders suchen müssen. Bei der Suche hier im Forum (Suchbegriff: CheckBox) hättest Du es auch hier finden können ;-) |
Hallo Christian,
wie Recht Du hast !!! :wink: Nachdem ich erfolgreich dieses Problem gelöst hatte, habe ich die Themen durchgesehen, mit Suchbegriffen experimentiert und mir die dazu gelieferten Ergebnisse angesehen. Und natürlich stieß ich ziemlich schnell auf Deine Antwort vom 13.11.2002 zu dem Thema "Viele viele CheckBox". Darin war die Lösung, die ich gesucht habe, quasi enthalten. Und was lernen wir daraus: Selbst Suchen will gelernt sein :dancer: mfg eddy |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:30 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