Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Methodenaufruf nur für Klassenmethoden und Konstruktoren (https://www.delphipraxis.net/183138-methodenaufruf-nur-fuer-klassenmethoden-und-konstruktoren.html)

DelphiNewbie929 15. Dez 2014 12:35

Delphi-Version: 5

Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,

ich bin Delphi-Neueinsteiger und noch ein wenig am rumexperimentieren und hänge auch schon fest. Was ich will ist dass ein bestimmter Button per Methode doppelt so groß oder halb so klein gemacht werden kann. Dazu will ich 2 Funktionen erstellen, die dann in das Klick-Event zweier anderer Buttons reinkommen sollen.
Folgend sieht es grad aus, aber ich verstehe nicht, warum ständig obiger Fehler kommt:

Delphi-Quellcode:
unit Unit44;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TMeinButton = class(TForm1)

  private
    { Private-Deklarationen }
  public
  procedure SetzeDoppelteGroeße(Sender : TObject);
  procedure SetzeHalbeGroeße(Sender: TObject);
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TMeinButton.SetzeHalbeGroeße(Sender: TObject);
begin
  Self.Width := Self.Width div 2;      //Breite des Übergabeobjektes verdoppeln
  Self.Height := Self.Height div 2;    //Höhe des Übergabeobjektes verdoppeln
end;

procedure TMeinButton.SetzeDoppelteGroeße(Sender: TObject);
begin
  Self.Width := Self.Width * 2;         //Breite des Übergabeobjektes halbieren
  Self.Height := Self.Height * 2;      //Höhe des Übergabeobjektes halbieren
end;



procedure TForm1.Button2Click(Sender: TObject);
begin
  TMeinButton.SetzeDoppelteGroeße(Button1);   //Button 1 soll als Beispiel übergeben werden --> FEHLERMELDUNG
end;

procedure TForm1.Button3Click(Sender: TObject);  //Button 1 soll als Beispiel übergeben werden --> FEHLERMELDUNG
begin
  TMeinButton.SetzeDoppelteGroeße(Button1);
end;

end.
PS: Ich hoffe ich habe das richtige Forum erwischt, ansonten bitte nochmal verschieben ;)

himitsu 15. Dez 2014 12:39

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Erstmal gehst du auf Self und nicht auf den Parameter, also wieso sollte dann die Große es Objektes im Parameter verändert werden? :zwinker:

Und dann willst du eine Klassen-Methode (class procedure), denn nur Jene kann man über die Klasse aufrufen.

Delphi-Quellcode:
class procedure SetzeDoppelteGroeße(Button: TButton);
class procedure SetzeHalbeGroeße(Button: TButton);

TMeinButton.SetzeDoppelteGroeße(Button1);
Aber eigentlich willst du doch bestimmt eher sowas?
Delphi-Quellcode:
procedure SetzeDoppelteGroeße;
procedure SetzeHalbeGroeße;

Button1.SetzeDoppelteGroeße;

DelphiNewbie929 15. Dez 2014 12:58

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Naja vllt ist Self erstmal nicht genau das richtige. Er soll ja die Werte vom übergebenen (hier Button) nehmen und verändern.

Wenn ich nun nach deiner ersten Methode vorgehe (btw. statt "self" - eine Variable namens "Button" übergebe) bekomme ich Fehler, weil sich obere Deklarationen von den unteren unterscheiden, und ebenso forward und Exteranal-Deklarationen ungenügend seien.

Was ich aber halt schon will ist eine eigene Klasse mit den Verdopplungs/Halbierungs-Methoden zu haben, die aufrufen kann


EDIT:
Es funktioniert nun doch wie gewünscht, ich habe dummerweise das "class" beim Methodenaufruf vergessen zu schreiben, daher die Fehlermeldungen ;)

Delphi-Quellcode:
class procedure TMeinButton.SetzeHalbeGroeße(Button: TButton);

Also danke dir, das ging wirklich flott und hat mir sehr geholfen!

himitsu 15. Dez 2014 13:21

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Bitte.

Zitat:

Delphi-Quellcode:
TMeinButton = class(TForm1)

Pssst: Bist'e sicher, daß dein Button eine Form ist?

DelphiNewbie929 15. Dez 2014 14:27

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Zitat:

Zitat von himitsu (Beitrag 1283460)
Pssst: Bist'e sicher, daß dein Button eine Form ist?

hmpf - schon geändert :roll:

BadenPower 15. Dez 2014 14:58

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,

Delphi-Quellcode:
  Self.Width := Self.Width div 2; //Breite des Übergabeobjektes verdoppeln
.

Hier hast Du natürlich auch Glück, dass bei der Zuweisung der Hälfte der Breite von Delphi das Ergebnis automatisch in eine Ganzzahl umgewandelt wird.

Die Hälfte von 47 wäre 23.5 was ein Extended und kein Integer wäre und strenggenommen eigentlich nicht der Property Width zugewiesen werden kann. Ein Round() wäre schön.


Vielleicht noch die Kommentare anpassen, damit sie mit dem übereinstimmen, was gemacht wird.

baumina 15. Dez 2014 15:05

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Zitat:

Zitat von BadenPower (Beitrag 1283473)
Hallo zusammen,

Delphi-Quellcode:
  Self.Width := Self.Width div 2; //Breite des Übergabeobjektes verdoppeln
.

Hier hast Du natürlich auch Glück, dass bei der Zuweisung der Hälfte der Breite von Delphi das Ergebnis automatisch in eine Ganzzahl umgewandelt wird.

Die Hälfte von 47 wäre 23.5 was ein Extended und kein Integer wäre und strenggenommen eigentlich nicht der Property Width zugewiesen werden kann. Ein Round() wäre schön.


Vielleicht noch die Kommentare anpassen, damit sie mit dem übereinstimmen, was gemacht wird.

Div liefert immer eine Ganzzahl.

DeddyH 15. Dez 2014 15:06

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Richtig, denn es ist ein ganzzahliger Operator, im Gegensatz zu "/".

mkinzler 15. Dez 2014 15:20

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Aber weder / noch DIV verdoppelt sondern beide halbieren

Zitat:

Delphi-Quellcode:
//Breite des Übergabeobjektes verdoppeln


Zoot 15. Dez 2014 15:25

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Zitat:

Zitat von mkinzler (Beitrag 1283480)
Aber weder / noch DIV verdoppelt sondern beide halbieren

Zitat:

Delphi-Quellcode:
//Breite des Übergabeobjektes verdoppeln


"*" halbiert ja auch nicht. :-D

Zitat:

Zitat von DelphiNewbie929 (Beitrag 1283454)

Delphi-Quellcode:
Self.Width := Self.Width * 2;         //Breite des Übergabeobjektes halbieren


mkinzler 15. Dez 2014 15:40

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Das komplette Zitat:
Zitat:

Delphi-Quellcode:
 Self.Width := Self.Width div 2; //Breite des Übergabeobjektes verdoppeln .


DeddyH 15. Dez 2014 15:56

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Es ist aber nur jeweils der Kommentar falsch, die Methoden tun schon das, was ihr Name beschreibt.

BadenPower 15. Dez 2014 15:58

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,
Zitat:

Zitat von baumina (Beitrag 1283476)
Div liefert immer eine Ganzzahl.

Hatte ich doch geschrieben.
Daher teilte ich lediglich mit, dass ein Round() schön wäre.

Ob jetzt wirklich sinnvoll, dass stellen wir beiseite, wenn er nur in Delphi programmiert.

Sir Rufo 15. Dez 2014 17:36

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Zitat:

Zitat von BadenPower (Beitrag 1283493)
Hallo zusammen,
Zitat:

Zitat von baumina (Beitrag 1283476)
Div liefert immer eine Ganzzahl.

Hatte ich doch geschrieben.
Daher teilte ich lediglich mit, dass ein Round() schön wäre.

Ob jetzt wirklich sinnvoll, dass stellen wir beiseite, wenn er nur in Delphi programmiert.

Er soll ernsthaft erst eine Float-Division machen um das Ergebnis dann wieder mit Round in einen Integer zu transferieren?

Da ist doch das DIV wesentlich ehrlicher und tut, was verlangt wird.

BadenPower 15. Dez 2014 18:27

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,
Zitat:

Zitat von Sir Rufo (Beitrag 1283511)
Da ist doch das DIV wesentlich ehrlicher und tut, was verlangt wird.

Das ist ohne Zweifel richtig.

Zitat:

Zitat von Sir Rufo (Beitrag 1283511)
Er soll ernsthaft erst eine Float-Division machen um das Ergebnis dann wieder mit Round in einen Integer zu transferieren?

Vielleicht denke ich manchmal etwas zu aufwendig, da ich bei Größenberechnungen von visuellen Komponenten gerne selbst entscheide, ob das Angezeigte nachher eine ungerade oder gerade Anzahl von Bildpunkten hat und daher meistens in einer Abfrage mit Ceil() und Floor() arbeite um einen gleichmäßigen Randabstand beizubehalten.

Dejan Vu 16. Dez 2014 06:42

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Zitat:

Zitat von BadenPower (Beitrag 1283517)
Vielleicht denke ich manchmal etwas zu aufwendig, da ich bei Größenberechnungen von visuellen Komponenten gerne selbst entscheide, ob das Angezeigte nachher eine ungerade oder gerade Anzahl von Bildpunkten hat und daher meistens in einer Abfrage mit Ceil() und Floor() arbeite um einen gleichmäßigen Randabstand beizubehalten.

Wie schaffst Du es, mit 'Ceil' und 'Floor' zu bestimmen, ob Du eine ungerade oder gerade Anzahl von Bildpunkten hast? Poste mal deinen Code, gerne auch in einem anderen Thread.

BadenPower 16. Dez 2014 09:05

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,
Zitat:

Zitat von Dejan Vu (Beitrag 1283537)
Wie schaffst Du es, mit 'Ceil' und 'Floor' zu bestimmen, ob Du eine ungerade oder gerade Anzahl von Bildpunkten hast? Poste mal deinen Code, gerne auch in einem anderen Thread.

Einfache Mathematik.

Quick and dirty mit einem Button und 3 Editfeldern zum Nachbauen:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  liNewValue: Integer;
  lfValue: Extended;
begin

  lfValue := StrToInt(Edit1.Text) / StrToInt(Edit2.Text);

  if ((Ceil(lfValue) mod 2) = 0) then
   begin
    liNewValue := Ceil(lfValue);
   end
  else
   begin
    liNewValue := Ceil(lfValue) + 1;
   end;

  Edit3.Text := IntToStr(liNewValue);

end;
Wenn Du Ceil() nimmst, dann kommt nie 0 heraus, ausser der Dividend ist 0. Natürlich solltest Du auch noch vor der Teilung abfragen, ob der Divisor 0 ist, um einen Fehler zu vermeiden.

Sir Rufo 16. Dez 2014 09:19

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Also du benötigst ein abgewandelten Integer DIV
Delphi-Quellcode:
function IntCeilDiv( Val1, Val2 : Integer ) : Integer;
begin
  Result := Val1 div Val2;
  if not ( Val1 mod Val2 = 0 ) then
    Inc( Result );
end;
und kannst dann
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  liNewValue: Integer;
begin

  liNewValue := IntCeilDiv( StrToInt(Edit1.Text), StrToInt(Edit2.Text) );

  if not ( liNewValue mod 2 = 0 ) then
    Inc( liNewValue );

  Edit3.Text := IntToStr(liNewValue);

end;
Hab ich das so richtig verstanden?

UPDATE
So geht es auch und ist damit kurz und knackig und man sieht auch sofort, was beabsichtigt ist
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  liNewValue: Integer;
begin

  liNewValue := Ceil( StrToInt(Edit1.Text) / StrToInt(Edit2.Text) );

  if not ( liNewValue mod 2 = 0 ) then
    Inc( liNewValue );

  Edit3.Text := IntToStr(liNewValue);

end;

himitsu 16. Dez 2014 09:20

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Delphi-Quellcode:
(x mod 2) = 0
... Du meinst also NOT Delphi-Referenz durchsuchenODD?

Zitat:

Delphi-Quellcode:
function IntCeilDiv( Val1, Val2 : Integer ) : Integer;
begin
  Result := Val1 div Val2;
  if Val1 mod Val2 <> 0 then
    Inc( Result );
end;

Immer aufrunden?

Delphi-Quellcode:
Result := (Val1 + 1) div 2;

Result := (Val1 + Val2 div 2) div Val2;
Vor dem Dividieren die Hälfte des Divisors hinzuaddiert, führt zu einem arithmetischem Aufrunden, da man den 0-Wert um die Hälfte (auf 0,5) verschoben hat. :stupid: (oder wie auch immer man das auf Mathematikdeutsch ausdrückt)

BadenPower 16. Dez 2014 10:29

AW: Methodenaufruf nur für Klassenmethoden und Konstruktoren
 
Hallo zusammen,

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  liNewValue: Integer;
begin

  liNewValue := Ceil( StrToInt(Edit1.Text) / StrToInt(Edit2.Text) );

  if not ( liNewValue mod 2 = 0 ) then
    Inc( liNewValue );

  Edit3.Text := IntToStr(liNewValue);

end;
So geht's natürlich auch, wenn Du den Float-Wert nicht noch für andere Berechnungen benötigst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:03 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