Autor Beitrag
Kay E.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 118



BeitragVerfasst: Fr 03.12.10 16:48 
Hallo zusammen!

Mir ist hier zwar nichts weltbewegendes aufgefallen, aber trotzdem würde ich gern wissen, warum mein Code das macht.
Es geht darum, dass ein Form als Modal angezeigt wird. Auf der Form sind nur Labels, Checkboxes und zwei Buttons. Das ganze soll eine Sicherheitsabfrage sein. Nur wenn alle Checkboxen angekreuzt sind, wird der StartProcessButton enabled. Der gibt wiederum ein mrOK zurück und das Hauptfenster arbeitet weiter.
Jetzt zum Problem an sich: Wenn ich die Sicherheitsabfrage ausführe und danach auf den Return-Button klicke (mrCancel) während ein paar Checkboxen checked sind, kann ich danach die Sicherheitsabfrage nochmal starten. Dazu setz ich die Zählvariable wieder auf Null zurück und "unchecke" die Checkboxen. Das spannende daran ist, dass durch die Wertänderung die OnClick-Prozedur aufgerufen wird - aber nur bei den Checkboxen, die davor noch checked waren! Und das nicht nur, wenn ich das mit FindComponent mache, sondern auch, wenn ich das manuell durchexerzier.

Wie kann sowas sein? Was passiert da und wie könnte ich das abstellen?

Danke für eure Tipps!

Hier noch der Code:
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:
private
  Checked: Integer;

const
  cNumCheckboxes = 10;

procedure TSecurityQueryStartForm.AllChecked(Bool: Boolean);
begin
  if Bool then
    inc(Checked)
  else
    dec(Checked);

  if Checked = cNumCheckboxes then
    StartProcessButton.Enabled := True
  else
    StartprocessButton.Enabled := False;
end;

procedure TSecurityQueryStartForm.CheckBox10Click(Sender: TObject);
begin
  AllChecked(CheckBox10.Checked);
end;

procedure TSecurityQueryStartForm.CheckBox1Click(Sender: TObject);
begin
  AllChecked(CheckBox1.Checked);
end;

//[...]

procedure TSecurityQueryStartForm.CheckBox9Click(Sender: TObject);
begin
  AllChecked(CheckBox9.Checked);
end;

procedure TSecurityQueryStartForm.FormShow(Sender: TObject);
var
  i: Integer;
begin
  Checked := 0;

  for i := 1 to cNumCheckboxes do
  begin
    TCheckbox(FindComponent('CheckBox' + inttostr(i))).Checked := False;
  end;

 {Problem tritt auch auf bei
  CheckBox1.Checked := False;
  ... 
  CheckBox10.Checked := False;
 }

end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 03.12.10 17:14 
Der Grund ist, dass eine solche Wertänderung auch durch z.B. die Leertaste ausgelöst werden kann, wenn die Komponente den Fokus hat. Deshalb wird dabei dann OnClick ausgelöst. OnClick beinhaltet dann die verschiedenen Möglichkeiten der Umschaltung.
In der Regel ist das ja auch sinnvoll, da eine CheckBox einen Status darstellt und entsprechend des Status etwas eingestellt wird.

Dass es nur bei denen passiert, die checked sind, liegt daran, dass bei den anderen keine Änderung des Wertes stattfindet und der Versuch daher direkt abgebrochen wird.

Wenn du dir selbst eine Komponente ableitest, kannst du darin ClicksDisabled auf True setzen, dann wird OnClick nicht mehr ausgelöst.

Einfacher ist, wenn du ein privates boolsches Feld deklarierst und das auf True setzt vorher. In deiner einen CheckBoxClick-Methode musst du dann nur noch schauen, ob das True ist. Und wenn ja, machst du einfach nichts.
// EDIT:
Warum hast du eigentlich mehrere CheckBoxXClick-Methoden? :shock: Die machen doch eh alle das selbe... :roll:

Ich verstehe aber auch nicht so ganz warum das eigentlich ein Problem ist. Schließlich ist es doch korrekt, dass die Anzahl zurückgesetzt wird, wenn der Wert auf unchecked gesetzt wird. Du musst doch einfach nur das nicht selbst ein zweites Mal machen... (also einfach Zeile 41 weg und gut ists...)
Kay E. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 118



BeitragVerfasst: Fr 03.12.10 17:51 
Ah ok. Ich fand das ungewöhnlich, dass die Komponente so auf eine Wertänderung reagiert. Das war mir bisher so noch nicht bewusst. Wenn man das nicht weiß, kann man ganz schön ins Fettnäpfchen laufen :)
Wie ich das Problem umgehe, war mir schon klar, nachdem mir das Problem aufgefallen ist. Mich hat nur interessiert, warum das so ist, wie es ist.
Und was das mit den 10 Prozeduren angeht... Ähm ja... *schäm* :oops: Der Beqeumlichkeit halber ein schnelles Copy-Paste. Habs grad geändert (ich weiß, sah schrecklich aus...).

Danke für die Aufklärung!