Delphi-PRAXiS
Seite 4 von 5   « Erste     234 5      

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 3. Dez 2010 14:46

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

Zitat von himitsu (Beitrag 1065897)
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.

Da ich das Senden der Message auch innerhalb des Objektes abhandle
Delphi-Quellcode:
procedure AdsRouterCallback( nEvent:Longint ); stdcall;
begin
  PostMessage(wndHandle, WM_ADSROUTERNOTIFICATION, nEvent, 0);
end;
müßte ich eine feste Liste für die verschiedenen Windows-Messages fest im Objekt integrieren und wäre dann darauf festgelegt.
Das wollte ich vermeiden.

himitsu 3. Dez 2010 15:08

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Delphi-Quellcode:
TMyObject = class(TComponent)
private
  FMessageID: LongWord;
protected
  procedure WndProc(Message: TMessage); override;
public
  constructor Create(Owner: TComponent; MessageID: LongWord);
  property MessageID: LongWord read FMessageID;
end;

procedure TMyObject.WndProc(Message: TMessage);
begin
  if Message.msg = MessageID then
  begin
    // mach was
  end;
end;

constructor TMyObject.Create(Owner: TComponent; MessageID: LongWord);
begin
  inherited Create(Owner);
  FMessageID := MessageID;
end;


id := WM_APP + 123;
obj := TMyObject.Create(nil, id);

PostMessage(obj.Handle, id, nEvent, 0);
obj.Perform(id, nEvent, 0);
oder irgendwie so

FriendOfDelphi 5. Dez 2010 15:12

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

Zitat von himitsu (Beitrag 1065935)
Delphi-Quellcode:
TMyObject = class(TComponent)
private
  FMessageID: LongWord;
protected
  procedure WndProc(Message: TMessage); override;
public
  constructor Create(Owner: TComponent; MessageID: LongWord);
  property MessageID: LongWord read FMessageID;
end;

procedure TMyObject.WndProc(Message: TMessage);
begin
  if Message.msg = MessageID then
  begin
    // mach was
  end;
end;

constructor TMyObject.Create(Owner: TComponent; MessageID: LongWord);
begin
  inherited Create(Owner);
  FMessageID := MessageID;
end;


id := WM_APP + 123;
obj := TMyObject.Create(nil, id);

PostMessage(obj.Handle, id, nEvent, 0);
obj.Perform(id, nEvent, 0);
oder irgendwie so

So ganz funktiniert das noch nicht.
Ich habe noch zwei Fragen:
1.) Wird die Methode
Delphi-Quellcode:
.WndProc
automatisch aufgerufen, nachdem
Delphi-Quellcode:
.Perform
ausgeführt wurde?
2.)
Delphi-Quellcode:
PostMessage
und damit wohl auch
Delphi-Quellcode:
.Perform
sollen innerhalb der Klasse aufgerufen werden. Wie muss das dann aussehen?

DeddyH 5. Dez 2010 15:18

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
WndProc ist der MessageHandler für alle Messages, die an Deine Komponente geschickt werden. Das bedeutet, dass sowohl PostMessage als auch Perform dazu führen (sollten), dass WndProc mit der entsprechenden Message durchlaufen wird. Falls nicht, hast Du irgend etwas falsch gemacht ;)

[edit] Achja, dazu müsste Deine Komponente aber von TControl abgeleitet sein, wenn ich nicht irre. [/edit]

FriendOfDelphi 5. Dez 2010 16:45

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Also so wurde das über eine fest verknüpfte Message gemacht:
Delphi-Quellcode:
[...schnipp...]

  TMeineKlasse = class(TWinControl)
    procedure WMAdsDeviceNotification(var Message: TMessage); message WM_ADSDEVICENOTIFICATION; //feste Zuordnung von Methode zur Windows-Message

[...schnipp...]

Procedure NotificationCallback(   pAddr:PAmsAddr;
                                pNotification:PAdsNotificationHeader;
                                hUser:Longword ); stdcall;
begin
    PostMessage( HWND(hUser), WM_ADSDEVICENOTIFICATION, 0, 0);
end;

[...schnipp...]
Die Windows-Message
Delphi-Quellcode:
message WM_ADSDEVICENOTIFICATION
ruft natürlich nur die Methode
Delphi-Quellcode:
procedure WMAdsDeviceNotification(var Message: TMessage)
auf.
Deshalb habe ich das jetzt folgendermaßen geändert:
Delphi-Quellcode:
Procedure NotificationCallback(   pAddr:PAmsAddr;
                                pNotification:PAdsNotificationHeader;
                                hUser:Longword ); stdcall;
begin
    PostMessage(HWND(hUser), lwMessageID , 0, 0);
    ???.Perform(lwMessageID, 0, 0); //Hier weiß ich nicht weiter
end;
Um diese feste Zuordnung aufzulösen, soll eine eigene Windows-Message, mit der bei der Erzeugung des Objektes übergebenen Message-ID ("lwMessageID") gesendet werden.
Das
Delphi-Quellcode:
PostMessage
ist wohl richtig.
Aber anschließend muss ja noch
Delphi-Quellcode:
WndProc
mit der entsprechenden Message durchlaufen werden.
Das löst man mit
Delphi-Quellcode:
Perform(lwMessageID, 0, 0)
aus, richtig?
Hier weiß ich nicht weiter.

DeddyH 5. Dez 2010 16:49

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Auch PostMessage sollte WndProc auslösen, wenn ich keinen Denkfehler mache. Innerhalb von WndProc kannst Du doch dann die übergebene Message prüfen und dementsprechend reagieren.

FriendOfDelphi 5. Dez 2010 17:26

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

Zitat von DeddyH (Beitrag 1066358)
Auch PostMessage sollte WndProc auslösen, wenn ich keinen Denkfehler mache. Innerhalb von WndProc kannst Du doch dann die übergebene Message prüfen und dementsprechend reagieren.

Ich habe wie in Nachricht #32 beschrieben im "protected"-Bereich
Delphi-Quellcode:
protected
  procedure WndProc(Message: TMessage); override;
eingefügt.

Bei
Delphi-Quellcode:
override;
meldet der Compiler den Fehler "Deklaration von 'WndProc' unterscheidet sich von vorheriger Deklaration."
Deshalb habe ich das
Delphi-Quellcode:
override;
gegen ein
Delphi-Quellcode:
overload;
ausgetauscht.

Und die Methode definiert:
Delphi-Quellcode:
procedure TMeineKlasse.WndProc(Message: TMessage);
begin
  if Message.msg = MessageID then
  begin
    // mach was
    ShowMessage('test');
  end;
end;
Soweit, so gut. Der Compiler meldet keinen Fehler.
Aber bei der Methodendefinition fehlen die "blauen" Punkte.
Die Methode wird also nicht mitcompiliert. :(

DeddyH 5. Dez 2010 17:29

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Wenn der Compiler meckert, tauscht man override einfach gegen overload? Eine sehr kreative Vorgehensweise. Wie wäre es denn mit
Delphi-Quellcode:
protected
  procedure WndProc(var Message: TMessage); override;
Nun könntest Du in der überladenen Methode einfach auf Deine Message prüfen und falls kein Treffer, inherited aufrufen, das sollte dann schon passen.

FriendOfDelphi 5. Dez 2010 18:06

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

Zitat von DeddyH (Beitrag 1066365)
Wenn der Compiler meckert, tauscht man override einfach gegen overload? Eine sehr kreative Vorgehensweise. Wie wäre es denn mit
Delphi-Quellcode:
protected
  procedure WndProc(var Message: TMessage); override;
Nun könntest Du in der überladenen Methode einfach auf Deine Message prüfen und falls kein Treffer, inherited aufrufen, das sollte dann schon passen.

:oops: Ich muss wohl noch viel lernen. Dachte, es wäre ein Schreibfehler...

Ich habe jetzt noch folgendes Problem:
Delphi-Quellcode:
[...schnipp...]

  TMeineKlasse = class(TWinControl)
    procedure WMAdsDeviceNotification(var Message: TMessage); message WM_ADSDEVICENOTIFICATION; //feste Zuordnung von Methode zur Windows-Message
  private
    { Private-Deklarationen }
    FMessageID: LongWord;

[...schnipp...]

  public
    { Public-Deklarationen }
    property MessageID: LongWord read FMessageID;

[...schnipp...]
Ich kann die Property/Eigenschaft
Delphi-Quellcode:
TMeineKlasse.MessageID
in der Prozedur
Delphi-Quellcode:
Procedure NotificationCallback(   pAddr:PAmsAddr;
                                pNotification:PAdsNotificationHeader;
                                hUser:Longword ); stdcall;
begin
    PostMessage(HWND(hUser), TMeineKlasse.MessageID , 0, 0);
end;
nicht verwenden.
Der Compiler meldet den Fehler "Methodenbezeichner erwartet".
Kennt er die zu dem Zeitpunkt noch nicht?

DeddyH 5. Dez 2010 18:15

AW: Wie kann ein Zeiger auf eine Funktion als Paramater übergeben werden?
 
Du brauchst eine Methode. Eine solche gehört immer zu einer Klasse.
Delphi-Quellcode:
procedure Wuppdi; //reguläre Prozedur

procedure TEineKlasse.Wuppdi; //Methode der Klasse TEineKlasse


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 Uhr.
Seite 4 von 5   « Erste     234 5      

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