Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Sender abfragen klappt nicht richtig (https://www.delphipraxis.net/179285-sender-abfragen-klappt-nicht-richtig.html)

Bjoerk 24. Feb 2014 20:45

Sender abfragen klappt nicht richtig
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab einen kleinen Objectinspektor (Siehe Anlage). Die einzelnen Zeilen sind z.B. so aufgebaut.

Delphi-Quellcode:
  TPropComboBox = class(TComboBox)
  private
    Info: TEdit;
    CheckBox: TCheckBox;
    procedure SetTopIndex(const Value: integer);
    procedure SetVisible(const Value: boolean);
  public
    property TopIndex: integer write SetTopIndex;
    property Visible: boolean write SetVisible;
    constructor Create(AOwner: TComponent); override;
  end;

{ TPropComboBox }

constructor TPropComboBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Info := TEdit.Create(Self);
  CheckBox := TCheckBox.Create(Self);
end;

procedure TPropComboBox.SetTopIndex(const Value: integer);
begin
  Top := (Value - 1) * 25 + 40;
  Info.Top := Top;
  CheckBox.Top := Top;
  TabOrder := Value;
end;

procedure TPropComboBox.SetVisible(const Value: boolean);
begin
  inherited Visible := Value;
  Info.Visible := Value;
end;
Erzeugen tue ich eine Reihe z.B. so:
Delphi-Quellcode:
function TDrawPadProperties.CreateComboBox(const Name, Text: string;
  const Tag: TProp): TPropComboBox;
begin
  Result := TPropComboBox.Create(FOwner);
  Result.Name := NameSubStr + Name + '_Prop';
  Result.Parent := FOwner.Pages[0];
  Result.Visible := false;
  Result.Left := 155;
  Result.Width := 130;
  Result.Style := csOwnerDrawFixed;
  Result.Font.Assign(FFontBlack);
  Result.OnClick := EditExit;
  Result.Tag := Integer(Tag);
  Result.ShowHint := Length(Text) > 20;
  Result.Hint := Text;

  Result.Info.Name := NameSubStr + Name + '_PropInfo';
  Result.Info.Parent := FOwner.Pages[0];
  Result.Info.Left := 20;
  Result.Info.Width := 130;
  Result.Info.ReadOnly := true;
  Result.Info.TabStop := false;
  Result.Info.Font.Assign(FFontInfo);
  Result.Info.Text := Text;

  if not FSimple then
  begin
    Result.CheckBox.Name := NameSubStr + Name + '_MultiProp';
    Result.CheckBox.Parent := FOwner.Pages[0];
    Result.CheckBox.Visible := false;
    Result.CheckBox.Left := 290;
    Result.CheckBox.Width := 20;
    Result.CheckBox.Height := 20;
    Result.CheckBox.Font.Assign(FFontBlack);
    Result.CheckBox.TabStop := false;
    Result.CheckBox.Caption := '';
    Result.CheckBox.OnClick := EditExit;
    Result.CheckBox.Tag := Integer(Tag);
    Result.CheckBox.ShowHint := true;
    Result.CheckBox.Hint := 'Auf alle markierten Objekte anwenden';
  end;
end;
In OnExit (= OnClick für diese Komponente) frage ich den Sender ab. Klappt aber nicht (***)?

Delphi-Quellcode:
function TDrawPadProperties.GetAll(Sender: TObject): integer; // ****
begin
  Result := 0;
  if not FSimple then
  begin
    if Sender is TCheckBox then
      if TCheckBox(Sender).Checked and (Pos('_MultiProp', TControl(Sender).Name) > 0) then
        Result := 1;
    if Result = 0 then
    begin
      if Sender is TPropCheckBox then
        if TPropCheckBox(Sender).CheckBox.Checked then
          Result := 2
        else
          if Sender is TPropEdit then
            if TPropEdit(Sender).CheckBox.Checked then
              Result := 3
            else
              if Sender is TPropComboBox then
                if TPropComboBox(Sender).CheckBox.Checked then
                  Result := 4;
    end;
  end;
  // ShowMessage(TControl(Sender).Name);
end;

procedure TDrawPadProperties.EditExit(Sender: TObject);
var
  All: boolean;
begin
  if FEnabled and Assigned(FOnPropertiesChange) then
  begin
    StoreToStringList(FSL2);
    All := GetAll(Sender) <> 0; // ***
    if All or (not Compare) then
    begin
      FSL1.Assign(FSL2);
      FOnPropertiesChange(TProp(TControl(Sender).Tag), All);
    end;
  end;
end;
Die GetAll reagiert nicht so wie beabsichtigt. Die soll sagen, wenn OnExit (=ComboBoxClick) betätigt wird, ob die abgehängte Checkbox gecheckt ist (liefert Result = 0)?

Im Beispiel habe ich Stiftfarbe auf himmelblau gesetzt. Wie man sieht ist nur ein Object himmelblau dargestellt (sollten aber alle sein weil eben die dazugehörige Checkbox gecheckt ist). :gruebel:

Bjoerk 25. Feb 2014 00:47

AW: Sender abfragen klappt nicht richtig
 
Ich fass es nicht, da fehlten 2 begin's und end's. :shock:
Delphi-Quellcode:
      if Sender is TPropCheckBox then
      begin
        if TPropCheckBox(Sender).CheckBox.Checked then
          Result := 2
      end
      else
        if Sender is TPropEdit then
        begin
          if TPropEdit(Sender).CheckBox.Checked then
            Result := 3
        end
        else
          if Sender is TPropComboBox then
            if TPropComboBox(Sender).CheckBox.Checked then
              Result := 4;

Medium 25. Feb 2014 01:35

AW: Sender abfragen klappt nicht richtig
 
Das sieht mir insgesamt etwas verkrampft aus, da steigt doch niemand durch so. Ich hab die noch falsche Version genommen, und so hin geschrieben, wie ich dann endlich eine Chance hatte sie nachzuvollziehen. Die ganze Verschachtelung die du da anstellt ist viel komplizierter als nötig.

Delphi-Quellcode:
function TDrawPadProperties.GetAll(Sender: TObject): integer; // ****
begin
  Result := 0;
  if not FSimple then
  begin
    if (Sender is TCheckBox) and TCheckBox(Sender).Checked and (Pos('_MultiProp', TControl(Sender).Name) > 0) then
      Result := 1
    else
    if (Sender is TPropCheckBox) and TPropCheckBox(Sender).CheckBox.Checked then
      Result := 2
    else
    if (Sender is TPropEdit) and TPropEdit(Sender).CheckBox.Checked then
      Result := 3
    else
    if (Sender is TPropComboBox) and TPropComboBox(Sender).CheckBox.Checked then
      Result := 4;
  end;
  // ShowMessage(TControl(Sender).Name);
end;
Edit: Die vollständige Auswertung Bool'scher Ausdrücke sollte hierbei abgeschaltet bleiben (ist sie standardmäßig), dann bricht ein "if" nämlich sofort ab, wenn das Ergebnis fest steht und prüft die nachstehenden Bedingungen nicht mehr ab. Heisst hier: Wenn (Sender is TPropEdit) bereits false ist, und nachfolgende Bedingungen nur aufgeundet werden, wird der nachfolgende (möglicherweise ungültige) Cast erst gar nicht gemacht. False and "egal was" ist immer false.

Bjoerk 25. Feb 2014 07:55

AW: Sender abfragen klappt nicht richtig
 
Ok. Entscheidet der Compiler aber gelegentlich nicht selbst in welcher Reihenfolge er auswertet?

Nersgatt 25. Feb 2014 08:14

AW: Sender abfragen klappt nicht richtig
 
Nein, macht er so nicht.

So wie Medium es geschrieben hat, kann man das gefahrlos machen. Wie er schon sagte unter der Voraussetzung, dass die vollständige Boolsche Auswertung ausgeschaltet ist.

DeddyH 25. Feb 2014 08:20

AW: Sender abfragen klappt nicht richtig
 
Und wenn man sich etwas mehr Tipparbeit macht, sollte auch diese Einstellung keine Rolle mehr spielen:
Delphi-Quellcode:
function TDrawPadProperties.GetAll(Sender: TObject): integer; // ****
begin
  Result := 0;
  if not FSimple then
  begin
    if (Sender is TCheckBox) then
      begin
        if TCheckBox(Sender).Checked and (Pos('_MultiProp', TControl(Sender).Name) > 0) then
          Result := 1;
      end
    else if (Sender is TPropCheckBox) then
      begin
        if TPropCheckBox(Sender).CheckBox.Checked then
          Result := 2;
      end
    else if (Sender is TPropEdit) then
      begin
        if TPropEdit(Sender).CheckBox.Checked then
          Result := 3;
      end
    else if (Sender is TPropComboBox) then
      begin
        if TPropComboBox(Sender).CheckBox.Checked then
          Result := 4;
      end;
  end;
  // ShowMessage(TControl(Sender).Name);
end;

Bjoerk 25. Feb 2014 10:29

AW: Sender abfragen klappt nicht richtig
 
Jetzt muß ich doch nochmal nachfragen. Wenn TPropCheckBox von TCheckBox abgeleitet ist dann kann TPropCheckBox doch auch den Sender TCheckBox haben, oder nicht?

Nersgatt 25. Feb 2014 10:36

AW: Sender abfragen klappt nicht richtig
 
Der Sender ist ja nicht der Typ, sondern die Instanz.

Deine Ableitung sieht ja so aus:
TObject -> TWinControl -> TButtonControl -> TCustomCheckBox -> TCheckBox -> TPropCheckBox
Ich hoffe, ich hab keinen Schritt vergessen.

Du kannst also Deinen Sender auf jeden dieser Typen casten, wenn der Sender ein TPropCheckBox ist.

Bjoerk 25. Feb 2014 10:50

AW: Sender abfragen klappt nicht richtig
 
OK. Thanx. BTW, TControl kommt natürlich noch dazu (vor TWinControl).

DeddyH 25. Feb 2014 10:59

AW: Sender abfragen klappt nicht richtig
 
Also wenn schon, dann TObject -> TPersistent -> TComponent -> TControl -> TWinControl -> TButtonControl -> TCustomCheckBox -> TCheckBox -> TPropCheckBox. Ist das nun geklärt? :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:58 Uhr.
Seite 1 von 2  1 2      

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 by Thomas Breitkreuz