Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Individuelle, eigene Messages erzeugen und abarbeiten (https://www.delphipraxis.net/156604-individuelle-eigene-messages-erzeugen-und-abarbeiten.html)

FriendOfDelphi 8. Dez 2010 16:26

Delphi-Version: 5

Individuelle, eigene Messages erzeugen und abarbeiten
 
Hallo Wissende,

ich bin am verzweifeln.
Kann mal jemand kurz und knapp erläutern, wie man eigene, individuelle Windows-Messages erzeugt und abarbeitet.

Herausgefunden habe ich bis jetzt folgendes:
Windows-Messages erzeugt man u. a. durch
Delphi-Quellcode:
BOOL PostMessage(
    HWND hWnd,   // handle of destination window
    UINT Msg,   // message to post
    WPARAM wParam,   // first message parameter
    LPARAM lParam    // second message parameter
   );
Soweit ich weiter verstanden habe, wird dadurch automatisch
Delphi-Quellcode:
.WndProc(var Message: TMessage)
aufgerufen und man kann innerhalb der Prozedur darauf reagieren.
Was mache falsch, wenn a)
Delphi-Quellcode:
.WndProc
nicht aufgerufen wird oder wenn b)
Delphi-Quellcode:
var Message
nicht gleich
Delphi-Quellcode:
Msg
von
Delphi-Quellcode:
PostMessage
ist?

Luckie 8. Dez 2010 20:58

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Kannst du dein Problem bitte noch mal genauer erläutern?

FriendOfDelphi 8. Dez 2010 21:32

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von Luckie (Beitrag 1067200)
Kannst du dein Problem bitte noch mal genauer erläutern?

Ich erzeuge mit
Delphi-Quellcode:
PostMessage(HWND(hUser), hUser, 0, 0);
eine Windows-Message.

In meiner Klasse habe ich eine eigene
Delphi-Quellcode:
.WndProc
-Methode implementiert:
Delphi-Quellcode:
procedure TMeineKlasse.WndProc(var Message: TMessage);
begin
  begin
    // mach was
  end;
  inherited;
end;
Soweit ich das verstanden habe müßte diese nach dem Senden aufgerufen werden.
Aber das passiert nicht.
Was mache ich falsch?

Luckie 8. Dez 2010 21:45

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Hast du auch eine Nachrichtenschleife, die die Nachrichten aus der Nachrichtenschlange abholt und die WndProc weitergibt?

s.h.a.r.k 8. Dez 2010 22:02

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Ich handhabe das immer so:

-- EDIT: Funktionierender Code drei Posts weiter unten.

Hat bisher immer geklappt.

FriendOfDelphi 8. Dez 2010 22:21

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von Luckie (Beitrag 1067215)
Hast du auch eine Nachrichtenschleife, die die Nachrichten aus der Nachrichtenschlange abholt und die WndProc weitergibt?

Nein. Ich wußte nicht, dass man eine solche braucht.
Wie muss ich das denn machen?

FriendOfDelphi 8. Dez 2010 22:26

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1067220)
Ich handhabe das immer so:
Delphi-Quellcode:
const
  WM_MY_MESSAGE = WM_USER + 100;

type
TTest = class(TObject)
private
  procedure WndProc(var Msg: TMessage);
  procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
end;

procedure TTest.WndProc(var Msg: TMessage);
begin
  Dispatch(Msg);
end;

procedure TTest.OnStartupMessage(var Msg: TMessage);
begin
  if (Msg.Msg = WM_MY_MESSAGE) then
  begin

  end;
end;
Hat bisher immer geklappt.

Das habe ich auch schon so hinbekommen.
Aber: Ich möchte die Verbindung zwischen der aufrufenden Windows-Message und der durch diese aufgerufenen Prozedur nicht fest in der Klasse implementieren.
Die Message-ID soll dem Objekt beim Create mit übergeben werden können. Daher kann ich nicht mit einer Konstanten arbeiten.

s.h.a.r.k 8. Dez 2010 22:39

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Ich muss auch noch schnell zurück rudern! Das Problem an meinem Code ist, dass das (Window-)Handle fehlt, an welches die Nachricht geschickt werden kann. Denn nur dann wird die
Delphi-Quellcode:
WndProc()
angesprungen.

Hier die funktionierende Version.
Delphi-Quellcode:
const
  WM_MY_MESSAGE = WM_USER + 100;

type
TTest = class(TObject)
private
  FHandle : HWND;
  procedure WndProc(var Msg: TMessage);
  procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
public
  constructor Create(); reintroduce;
  destructor Destroy(); override;
end;

procedure TTest.WndProc(var Msg: TMessage);
begin
  Dispatch(Msg);
end;

procedure TTest.OnStartupMessage(var Msg: TMessage);
begin
  if (Msg.Msg = WM_MY_MESSAGE) then
  begin

  end;
end;

constructor TTest.Create();
begin
  inherited Create();
  FHandle := Classes.AllocateHWnd(Self.WndProc);
end;

destructor TTest.Destroy();
begin
  DeallocateHWnd(FHandle);
  inherited Destroy();
end;
-- EDIT: Dann bau halt eine passende if-Abfrage in die WndProc-Methode ein.

FriendOfDelphi 8. Dez 2010 22:56

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von s.h.a.r.k (Beitrag 1067244)
Ich muss auch noch schnell zurück rudern! Das Problem an meinem Code ist, dass das (Window-)Handle fehlt, an welches die Nachricht geschickt werden kann. Denn nur dann wird die
Delphi-Quellcode:
WndProc()
angesprungen.

Hier die funktionierende Version.
Delphi-Quellcode:
const
  WM_MY_MESSAGE = WM_USER + 100;

type
TTest = class(TObject)
private
  FHandle : HWND;
  procedure WndProc(var Msg: TMessage);
  procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
public
  constructor Create(); reintroduce;
  destructor Destroy(); override;
end;

procedure TTest.WndProc(var Msg: TMessage);
begin
  Dispatch(Msg);
end;

procedure TTest.OnStartupMessage(var Msg: TMessage);
begin
  if (Msg.Msg = WM_MY_MESSAGE) then
  begin

  end;
end;

constructor TTest.Create();
begin
  inherited Create();
  FHandle := Classes.AllocateHWnd(Self.WndProc);
end;

destructor TTest.Destroy();
begin
  DeallocateHWnd(FHandle);
  inherited Destroy();
end;
-- EDIT: Dann bau halt eine passende if-Abfrage in die WndProc-Methode ein.

Kann ich dann ganz auf
Delphi-Quellcode:
procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
verzichten?

Verwende Delphi 5.
Delphi-Quellcode:
AllocateHWnd
kennt der Compiler nicht... :(

FriendOfDelphi 8. Mär 2011 14:20

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von FriendOfDelphi (Beitrag 1067249)
Zitat:

Zitat von s.h.a.r.k (Beitrag 1067244)
Ich muss auch noch schnell zurück rudern! Das Problem an meinem Code ist, dass das (Window-)Handle fehlt, an welches die Nachricht geschickt werden kann. Denn nur dann wird die
Delphi-Quellcode:
WndProc()
angesprungen.

Hier die funktionierende Version.
Delphi-Quellcode:
const
  WM_MY_MESSAGE = WM_USER + 100;

type
TTest = class(TObject)
private
  FHandle : HWND;
  procedure WndProc(var Msg: TMessage);
  procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
public
  constructor Create(); reintroduce;
  destructor Destroy(); override;
end;

procedure TTest.WndProc(var Msg: TMessage);
begin
  Dispatch(Msg);
end;

procedure TTest.OnStartupMessage(var Msg: TMessage);
begin
  if (Msg.Msg = WM_MY_MESSAGE) then
  begin

  end;
end;

constructor TTest.Create();
begin
  inherited Create();
  FHandle := Classes.AllocateHWnd(Self.WndProc);
end;

destructor TTest.Destroy();
begin
  DeallocateHWnd(FHandle);
  inherited Destroy();
end;
-- EDIT: Dann bau halt eine passende if-Abfrage in die WndProc-Methode ein.

Kann ich dann ganz auf
Delphi-Quellcode:
procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
verzichten?

Verwende Delphi 5.
Delphi-Quellcode:
AllocateHWnd
kennt der Compiler nicht... :(

Da das Thema immer noch aktuell ist, möchte ich diesen Post noch einmal aufleben lassen.
Wie kann ich denn den Lösungsansatz von s.h.a.r.k ohne
Delphi-Quellcode:
AllocateHWnd
unter Delphi 5 realisieren?

DeddyH 8. Mär 2011 15:06

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Wer suchet, der findet: http://www.delphipraxis.net/98484-%5...elphi-5-a.html

FriendOfDelphi 8. Mär 2011 15:31

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von DeddyH (Beitrag 1086803)

Leider nicht.
Ich habe sogar beide Units mit eingebunden; Unit Forms und Unit Classes.
Der Compiler meldet trotzdem den Fehler "Undefinierter Bezeichner: 'AllocateHWnd'".

DeddyH 8. Mär 2011 16:07

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Und die Delphi-Hilfe findet auch nichts? Da müsste die Unit nämlich drinstehen.

C.Schoch 8. Mär 2011 16:27

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Hi,

Hast du das Classes. vor AllocateHWnd entfernt oder durch Forms. ersetzt?
Sonst sucht der Compiler nämlich weiterhin in der Unit Classes

DeddyH 8. Mär 2011 16:29

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Stimmt, das hatte ich gar nicht gesehen. Dann wird Forms also wohl doch richtig sein.

FriendOfDelphi 9. Mär 2011 10:51

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von C.Schoch (Beitrag 1086835)
Hi,

Hast du das Classes. vor AllocateHWnd entfernt oder durch Forms. ersetzt?
Sonst sucht der Compiler nämlich weiterhin in der Unit Classes

Ich hatte zunächst beide Units mit eingebunden. Und zwar in der Reihenfolge zuerst die Unit "Classes" und dann die Unit "Forms".
Damit meldet der Compiler den Fehler "Undefinierter Bezeichner: 'AllocateHWnd'".
Nach Deinem Tipp habe ich die Unit "Classes" ausdokumentiert und die Unit "Forms" belassen.
Damit meldet der Compiler den Fehler "Undefinierter Bezeichner: 'Classes'".
Beides in der Zeile
Delphi-Quellcode:
FHandle := Classes.AllocateHWnd(Self.WndProc);

DeddyH 9. Mär 2011 10:54

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Genau aus der Zeile sollst Du das "Classes." rausnehmen.

FriendOfDelphi 9. Mär 2011 12:17

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von DeddyH (Beitrag 1086965)
Genau aus der Zeile sollst Du das "Classes." rausnehmen.

Oh, da habe ich wohl nicht richtig gelesen... :oops:
Funktioniert; der Compiler meldet keine Fehler mehr. :)

Wie funktioniert denn das jetzt; wie kann ich das Ganze jetzt zum Leben erwecken?
Muss ich zur Laufzeit mit
Delphi-Quellcode:
PostMessage(...)
eine eigene Message mit den entsprechenden Parametern erzeugen, die dann dafür sorgt das die zugeordnete Prozedur (hier: OnStartupMessage(...)) aufgerufen wird und in dieser dann die übergebene ID abfragen? :?:

himitsu 9. Mär 2011 13:03

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Und nun nochmal zu den Grundlagen, was individuelle/eigene Messages angeht...

Hier erstmal die wichtigesten Bereiche:
MSDN-Library durchsuchenWM_USER bis WM_USER+31743 aka $0400 bis $7FFF
MSDN-Library durchsuchenWM_APP bis WM_APP+16383 aka $8000 bis $BFFF
$C000 bis $FFFF mit MSDN-Library durchsuchenRegisterWindowMessage
der Rest, also alles unter WM_USER und über $FFFF ist Windows vorbehalten.

Für den kleinen Anwendungsprogrammierer interessiert hier vorallem WM_USER+x und RegisterWindowMessage.

Bei WM_USER und WM_APP müssen die Programmierer aufpassen, daß sie möglichst keine Werte doppelt belegen (zumindestens nicht innerhalb von Klassen/Windows, welche diese Messages empfangen könnten.
Bei RegisterWindowMessage muß man nur aufpassen, daß der Name möglichst eindeutig ist und somit keine doppelten Message-IDs auftreten können.

RegisterWindowMessage ist eigentlich vorwiegend für Nachrichten von Anwendung zu einer anderen Anwendung vorgesehn, aber man kann sie auch innerhalb einer Anwendung nutzen.

FriendOfDelphi 9. Mär 2011 16:22

AW: Individuelle, eigene Messages erzeugen und abarbeiten
 
Zitat:

Zitat von himitsu (Beitrag 1086995)
Und nun nochmal zu den Grundlagen, was individuelle/eigene Messages angeht...

Hier erstmal die wichtigesten Bereiche:
MSDN-Library durchsuchenWM_USER bis WM_USER+31743 aka $0400 bis $7FFF
MSDN-Library durchsuchenWM_APP bis WM_APP+16383 aka $8000 bis $BFFF
$C000 bis $FFFF mit MSDN-Library durchsuchenRegisterWindowMessage
der Rest, also alles unter WM_USER und über $FFFF ist Windows vorbehalten.

Für den kleinen Anwendungsprogrammierer interessiert hier vorallem WM_USER+x und RegisterWindowMessage.

Bei WM_USER und WM_APP müssen die Programmierer aufpassen, daß sie möglichst keine Werte doppelt belegen (zumindestens nicht innerhalb von Klassen/Windows, welche diese Messages empfangen könnten.
Bei RegisterWindowMessage muß man nur aufpassen, daß der Name möglichst eindeutig ist und somit keine doppelten Message-IDs auftreten können.

RegisterWindowMessage ist eigentlich vorwiegend für Nachrichten von Anwendung zu einer anderen Anwendung vorgesehn, aber man kann sie auch innerhalb einer Anwendung nutzen.

Ok, dass erklärt, welche ID-Bereiche zur Verfügung stehen.
Aber wie verwende ich denn die eigenen Messages?
Wenn ich die Vorgehensweise wie oben im Link in der MSDN beschrieben, in Delphi übertrage, meldet das Programm beim ausführen in der Zeile
Delphi-Quellcode:
uFindReplaceMsg := RegisterWindowMessage(PChar(WM_MY_MESSAGE));
eine Zugriffsverletzung.
Kannst Du bitte ein Stück Beispielcode posten?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 Uhr.

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