Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden? (https://www.delphipraxis.net/156290-wie-kann-ein-zeiger-auf-eine-funktion-als-paramater-uebergeben-werden.html)

FriendOfDelphi 1. Dez 2010 13:44

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Ich möchte die zuvor beschriebene Lösung dahingehend erweitern, dass die übergebene Methode auf eine Windows Message reagiert.
Also in etwa so:
Es existiert eine Klasse die unter anderem Windows Messages abarbeitet.
Das Hauptprogramm, welches diese Klasse verwendet, soll der Klasse eine Methode übergeben, die dann ausgeführt wird, wenn die entsprechende Windows Message auftritt.

Wie kann ich das realisieren, bzw. wie muss der oben beschriebene Quellcode angepasst werden? :?:

DeddyH 1. Dez 2010 13:54

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Mal aus dem Kopf:
Delphi-Quellcode:
type
  TOnBestimmteMessage = procedure of object;

  TDeineKlasse = class
  private
    FOnBestimmteMessage: TOnBestimmteMessage;
    procedure SetOnBestimmteMessage(const value: TOnBestimmteMessage);
  public
    procedure MachWas;
    property OnBestimmteMessage: TOnBestimmteMessage read FOnBestimmteMessage write SetOnBestimmteMessage;
  end;

...

procedure TDeineKlasse.MachWas;
begin
  //irgendwelcher Code
  if Assigned(FOnBestimmteMessage) then
    FOnBestimmteMessage;
  //ggf. weiterer Code
end;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  DeineKlasse := TDeineKlasse.Create;
  DeineKlasse.OnBestimmteMessage := kompatible_Methode;
end;

FriendOfDelphi 1. Dez 2010 16:26

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Zitat:

Zitat von DeddyH (Beitrag 1065427)
Mal aus dem Kopf:
Delphi-Quellcode:
type
  TOnBestimmteMessage = procedure of object;

  TDeineKlasse = class
  private
    FOnBestimmteMessage: TOnBestimmteMessage;
    procedure SetOnBestimmteMessage(const value: TOnBestimmteMessage);
  public
    procedure MachWas;
    property OnBestimmteMessage: TOnBestimmteMessage read FOnBestimmteMessage write SetOnBestimmteMessage;
  end;

...

procedure TDeineKlasse.MachWas;
begin
  //irgendwelcher Code
  if Assigned(FOnBestimmteMessage) then
    FOnBestimmteMessage;
  //ggf. weiterer Code
end;

...

procedure TForm1.FormCreate(Sender: TObject);
begin
  DeineKlasse := TDeineKlasse.Create;
  DeineKlasse.OnBestimmteMessage := kompatible_Methode;
end;

Hmm, dass habe ich noch nicht ganz verstanden...
Ich probiers mal:

1.0) Zuerst wird wieder ein eigener Datentyp definiert:
Delphi-Quellcode:
TOnBestimmteMessage = procedure of object;
. Mit diesem kann man nun wieder Variablen deklarieren, die eine Methode darstellen. - Verstanden.
2.1) Als nächstes wird dann wieder eine Variable/ein Feld von diesem Typ (
Delphi-Quellcode:
FOnBestimmteMessage: TOnBestimmteMessage;
) und
2.2) eine Prozedur
Delphi-Quellcode:
procedure SetOnBestimmteMessage(const value: TOnBestimmteMessage);
, die die Variable/das Feld setzen kann, deklariert. - Verstanden.
3.1) Nun wird die Prozedur
Delphi-Quellcode:
procedure MachWas;
und
3.2) die Eigenschaft/Property
Delphi-Quellcode:
property OnBestimmteMessage: TOnBestimmteMessage read FOnBestimmteMessage write SetOnBestimmteMessage;
zum Lesen und Schreiben von außerhalb der Klasse deklariert. - Soweit erst einmal verstanden.
4.0) Jetzt folgt noch die Definition der Methode "MachWas":
Delphi-Quellcode:
procedure TDeineKlasse.MachWas;
begin
  //irgendwelcher Code
  if Assigned(FOnBestimmteMessage) then
    FOnBestimmteMessage;
  //ggf. weiterer Code
end;
. - Die Methode "MachWas" für sich allein gesehen, habe ich wohl auch verstanden.
Die Methode prüft, ob die entsprechende Windows Message aufgetreten ist.
Wenn dies der Fall ist, wird die zugewiesene Methode über des Feld
Delphi-Quellcode:
FOnBestimmteMessage
, das eine Methode darstellt ausgeführt, richtig?
Aber wann wird die Methode "MachWas" aufgerufen?
Übernimmt Delphi die Erkennung der Windows Message und die automatische Ausführung der Methode "MachWas"?
Wo wird Delphi das mitgeteilt?

DeddyH 1. Dez 2010 16:31

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Wann die Methode aufgerufen wird, bestimmst Du doch selbst in Deiner Klasse. Nach Deiner eigenen Aussage wäre das dann die Behandlung einer bestimmten Windows-Message, so dass "MachWas" dann ein Message-Handler sein müsste.

FriendOfDelphi 2. Dez 2010 17:46

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Zitat:

Zitat von DeddyH (Beitrag 1065465)
Wann die Methode aufgerufen wird, bestimmst Du doch selbst in Deiner Klasse. Nach Deiner eigenen Aussage wäre das dann die Behandlung einer bestimmten Windows-Message, so dass "MachWas" dann ein Message-Handler sein müsste.

Ja, stimmt.
Ich mache das mit einer eigenen Message-Handling-Methode.
Das ist hier ganz gut erklärt:http://www.podgoretsky.pri.ee/ftp/Do.../messages.html.

Das Ganze funktioniert für ein Objekt auch tadellos.
Wenn ich ein zweites, oder weitere Objekte erstelle (instanziiere), wird nur die Windows-Message für das zuletzt erstellte Objekt richtig verarbeitet.
Ich habe auch schon eine Vermutung worin das Problem besteht, aber nicht, wie ich es beseitigen kann.
Das Problem liegt wahrscheinlich in der Deklaration des Windows-Message-Nummer:
Delphi-Quellcode:
[...schnipp...]
const
  WM = WM_APP + 400;
[...schnipp...]
Jedes Objekt erhält in der Klasse dieselbe Windows-Message-Nummer.
Ich müßte die als Parameter mit übergeben.
In etwa so:
Delphi-Quellcode:
[...schnipp...]
const
  WM_variabel = WM_APP + iWMNr; //iWMNr soll der übergebene Parameter sein.
[...schnipp...]
Da dies aber eine Konstante sein muss und diese ganz am Anfang definiert wird, meckert der Compiler natürlich, dass er die Variable nicht kennt.
Gibt es dafür eine andere Lösungsmöglichkeit?

himitsu 2. Dez 2010 18:08

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Delphi-Quellcode:
protected
  procedure WndProc(var Message: TMessage); override;

if Message.Msg = WM_APP + x then
Notfalls kann man auch über MSDN-Library durchsuchenRegisterWindowMessage gehn.

Siehe das Bild in "Understanding the message-handling system"
WndProc ist die erste Anlaufstelle, wo alles durchkommt und (vermutlich) danach werden die entsprechenden Dispatch-Methoden ala
Delphi-Quellcode:
procedure NAME(var Message: TWM_TYPE); message WM_MESSAGE;
abgearbeitet.

FriendOfDelphi 2. Dez 2010 19:02

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Zitat:

Zitat von himitsu (Beitrag 1065725)
Delphi-Quellcode:
protected
  procedure WndProc(var Message: TMessage); override;

if Message.Msg = WM_APP + x then
Notfalls kann man auch über MSDN-Library durchsuchenRegisterWindowMessage gehn.

Siehe das Bild in "Understanding the message-handling system"
WndProc ist die erste Anlaufstelle, wo alles durchkommt und (vermutlich) danach werden die entsprechenden Dispatch-Methoden ala
Delphi-Quellcode:
procedure NAME(var Message: TWM_TYPE); message WM_MESSAGE;
abgearbeitet.

Besteht nicht die Möglichkeit an der Stelle
Delphi-Quellcode:
procedure NAME(var Message: TWM_TYPE); message WM_MESSAGE;
den Wert von "WM_MESSAGE" von außerhalb der Klasse als Parameter zu übergeben?

himitsu 2. Dez 2010 20:19

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Nein.

Dieses ist nunmal eine unveränderliche Konstante, welcher an dieser Stelle wärend des Compilierens genutzt wird.
Zur Laufzeit läßt sich dieses dann eben nicht mehr ändern.

Aber genau dafür kann man eben das WndProc (WindowProcedur) nutzen, wo alles vorbeikommt.

FriendOfDelphi 3. Dez 2010 12:43

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Zitat:

Zitat von himitsu (Beitrag 1065766)
Nein.

Dieses ist nunmal eine unveränderliche Konstante, welcher an dieser Stelle wärend des Compilierens genutzt wird.
Zur Laufzeit läßt sich dieses dann eben nicht mehr ändern.

Aber genau dafür kann man eben das WndProc (WindowProcedur) nutzen, wo alles vorbeikommt.

Ich kann Dir noch nicht so ganz folgen:
Ist das nicht eher ein Reagieren auf eine schon vorhandene Windows-Message-Nr.?
Ich möchte doch vielmehr jedem Objekt bei der Erzeugung/Instanziierung eine eigene Windows-Message-Nr. mitgeben, auf die es dann reagiert.

himitsu 3. Dez 2010 13:08

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Du gibst z.B. deinem Constructor die Message-ID mit, speicherst sie im Objekt und vergleichst dann damit via IF in WndProc und schon hat jedes Objekt seine eigene Nummer.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:23 Uhr.
Seite 3 von 5     123 45      

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