Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur (https://www.delphipraxis.net/190632-create-self-bei-ausgelagerter-funktion-methodenzeiger-und-regulaere-prozedur.html)

Freyr77 21. Okt 2016 13:01

Delphi-Version: 10 Seattle

Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Ich lagere gerade doppelte Funktionen/Prozeduren aus meinen Codes(zusammenhängend in einem Programm, aber jeder Code ein separater Programmbestandteil) in eine Art "Settings" Unit aus.

Jetzt bin ich auf ein Problem gestoßen.

Ich habe folgende Funktion:

Delphi-Quellcode:
var
  lChkBox: TGridCheckBox;

begin
  if (pColumn <> 0) AND (pRow = 0) then
    Exit;

  lChkBox := TGridCheckbox.Create(inherited);

  with lChkBox do
  begin
    Column := pColumn;
    Row := pRow;
    parent := Grid;

    Checked := True;
    Caption := '';
    Width := ChkboxWidth;
    Height := ChkboxHeight;
    OnMouseDown := CheckboxMouseDown;
    Visible := false;
    Invalidate;
  end;

  Grid.Objects[pColumn, pRow] := lChkBox;
  Result := lChkBox;
end;
.. die in beiden Codes vorkommt. Jetzt hab ich das Problem das er mir das Create(self) anmeckert, und komm gerade nicht auf die Lösung.
Ich dachte es geht mit "inherited", aber das ist es auch nicht.



Zweites Problem, in der gleichen Funktion. Hier wird ja "CheckBoxMouseDown" aufgerufen, welches ebenfalls in beiden Codes als Prozedur drinnen war. Das hab ich jetzt auch in meine "Settings" unit integriert, allerdings sagt er da jetzt "Inkompatible Typen: Methodenzeiger und reguläre Prozedur".

"CheckBoxMouseDown" sieht so aus:

Delphi-Quellcode:
var
  lChkBox: TGridCheckBox;
begin
  if Button = TMouseButton.mbLeft then
  begin
  lChkBox := (Sender as TGridCheckbox);
  lChkBox.Checked := not lChkBox.Checked;
  end;
end;

Union 21. Okt 2016 13:05

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Zitat:

"Inkompatible Typen: Methodenzeiger und reguläre Prozedur".
Methodenzeiger zeigt auf eine Methode und eine Prozedur ist standalone. Wenn Du solche Events umbiegen willst, müssen die auch in einer Klasse verpackt werden. Liegt an der Signatur von z.b. TNotifyEvent.

himitsu 21. Okt 2016 13:13

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Methoden-Zeiger haben 2 Zeiger drin (Zeiger auf Prozedur und den Zeiger auf's Objekt)
und Prozedurzeiger nur Einen. (Zeiger auf Prozedur)

Methoden haben einen unsichtbaren "Self"-Parameter. (außer statische Klassenmethoden).

Und dann gibt es noch Zeiger auf anonyme Methoden.


nur Variablen/Event-Property vom Typ "refereces to procedur/function" können Alles speichern.
Bei allem Anderen passt nur genau das rein, für was die Variable ausgelegt ist.

Freyr77 21. Okt 2016 13:14

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Also sollte ich diese "Checkbox"-Methoden lieber nicht auslagern um sie zusammenzufassen?

himitsu 21. Okt 2016 13:23

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Da Events nunmal Methoden-Zeiger sind, kannst du da auch nur Methoden zuweisen.

Methoten sind "Prozeduren", die in "irgendeiner" Klasse definiert sind.
Das können normale Instanz-Methoden (nur keine mit "static") oder Klassen-Methoden sein.

uligerhardt 21. Okt 2016 13:56

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Wenn du immer nur ein und dasselbe CheckboxMouseDown hast, würde ich das nicht über einen OnMouseDown-Handler lösen, sondern direkt TGridCheckbox.DoMouseDown überschreiben (oder heißt's TGridCheckbox.MouseDown?).

Blup 21. Okt 2016 15:06

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Vieleicht so:
Delphi-Quellcode:
TGridCheckBoxHelp = class(TComponent)
protected
  procedure CheckBoxMouseDown({...});
public
  procedure CreateCheckBox({...});
end;

procedure TGridCheckBoxHelp.CreateCheckBox({...});
var
  lChkBox: TGridCheckBox;

begin
  if (pColumn <> 0) AND (pRow = 0) then
    Exit;

  lChkBox := TGridCheckbox.Create(Grid); // Freigabe übernimmt das Grid oder Self

  with lChkBox do
  begin
    Column := pColumn;
    Row := pRow;
    parent := Grid;

    Checked := True;
    Caption := '';
    Width := ChkboxWidth;
    Height := ChkboxHeight;
    OnMouseDown := CheckboxMouseDown;
    Visible := false;
    Invalidate; // Invalidate für ein unsichtbares Steuerelement?
  end;

  Grid.Objects[pColumn, pRow] := lChkBox;
  Result := lChkBox;
end;

{z.B. im Show des Formulars}
FGridCheckBoxHelp := TGridCheckBoxHelp.Create(Self); // Freigabe übernimmt Self (das Formular)
FGridCheckBoxHelp.CreateCheckBox({...});

uligerhardt 22. Okt 2016 22:34

AW: Create(self) bei ausgelagerter Funktion, Methodenzeiger und reguläre Prozedur
 
Wenn du aus irgendeinem Grund den Weg mit Event Handler gehen willst, kannst du es mit Klassenmethoden versuchen - siehe https://stackoverflow.com/questions/...84676#11084676. Damit ersparst du dir das Erzeugen und Freigeben einer Dummy-Instanz (wie FGridCheckBoxHelp in Blups Post :mrgreen:).


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz