AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Problem bei der Verarbeitung von Systemnachrichten
Thema durchsuchen
Ansicht
Themen-Optionen

Problem bei der Verarbeitung von Systemnachrichten

Ein Thema von Johannes Maier · begonnen am 3. Sep 2004 · letzter Beitrag vom 4. Sep 2004
Antwort Antwort
Seite 1 von 2  1 2      
Johannes Maier

Registriert seit: 3. Sep 2004
25 Beiträge
 
Delphi 7 Professional
 
#1

Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 15:11
Hallo,

Mit einem Hilfsprogramm sende ich meinem Hauptprogramm die message WM_QUIT. Diese möchte ich nun abfangen, und als Reaktion ShowMessage('text') aufrufen. Das Problem:
Wenn ich im Hilfsprogramm die Nachricht mit SendMessage() verschicke, kann ich sie im Hauptprogramm mit der WndProc-Prozedur abfangen. Wenn ich WM_QUIT allerdings mittels PostMessage versende, dann schließt sich das Programm sofort, dabei möchte ich, dass nur meine Nachricht erscheint.
Ich habe es im Fall PostMessage bisher so versucht:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := ApplicationEvents1Message;
end;

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if Msg.Message = WM_QUIT then begin
    Handled := True;
    ShowMessage('WM_QUIT ist eingegangen');
  end;
end;
Damit sollte es doch eigentlich funktionieren... Jedenfalls wird nie die MessageBox angezeigt, und ich weiß nicht wieso ...
Achja, WndProc hab ich auch probiert, aber hab erfahren, dass die mit PostMessage gesendete Nachrichten nicht erhält.
Und noch was: WM_CLOSE oder WM_DESTROY lassen sich damit abfangen und anzeigen, aber WM_QUIT geht immer sofort durch und beendet das Programm OHNE vorher meine MessageBox anzuzeigen.
Ich hoffe mal hier weiß einer, wie man das Problem lösen kann
Johannes Maier
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 15:20
Zitat von MSDN:
The WM_QUIT message indicates a request to terminate an application and is generated when the application calls the PostQuitMessage function. It causes the GetMessage function to return zero.

WM_QUIT
nExitCode = (int) wParam; // exit code


Parameters

nExitCode

Value of wParam. Specifies the exit code given in the PostQuitMessage function.



Return Values

This message does not have a return value, because it causes the message loop to terminate before the message is sent to the application's window procedure.

See Also

GetMessage, PostQuitMessage
Laut dieser beschreibung Terminiert die Message das Programm, ohne direkt eine Message and die App zu senden.
  Mit Zitat antworten Zitat
Johannes Maier

Registriert seit: 3. Sep 2004
25 Beiträge
 
Delphi 7 Professional
 
#3

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 15:30
Gibt es dann überhaupt eine Möglichkeit, sein Programm so umzuschreiben, dass es diese Nachricht erhält, bevor es terminiert wird? Ich kenn mich da so genau jetzt nicht aus, aber dass man was mit PostQuitMessage anstellen kann, oder mit GetMessage, so dass auch bei WM_QUIT nicht 0 zurückgegeben wird? Vll. diese Funktion in seinem Programm überschreiben, denn wie ich das verstanden hab, gehen da die Nachrichten ein, und alle außer WM_QUIT gehen nicht sofort durch, nur WM_QUIT wird 0 zurckgeliefert und sofort abgebrochen.
Wenn einer diese Idee (falls es überhaupt geht) in einem kleinen Codebeispiel darstellen würde, wäre ich sehr dankbar
Johannes Maier
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#4

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 15:33
Wie es im MSDN stand:

Dein programm wird terminiert, BEVOR es die Message erhält. Du müsstest dein OS umschreiben, damit es vorher die Message noch bekommt.
  Mit Zitat antworten Zitat
Johannes Maier

Registriert seit: 3. Sep 2004
25 Beiträge
 
Delphi 7 Professional
 
#5

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 16:04
Hmm wenn ich Linus Torvalds Programmierskills hätte würde ich das jetzt tun
Also gibt es keine Möglichkeit, diese GetMessage-Funktion so zu ändern (nur für mein Programm, nicht systemweit), dass sie bei WM_QUIT nicht NULL ausgibt? Denn es heißt zwar, das Programm wird terminiert bevor es die message erhält, jedoch irgendwo muss diese ja ankommen, und zwar in dieser Message-Schleife ... Hmm aber so wichtig ist es nun auch wieder nicht Dann mach ich es lieber anders, mit WM_DESTROY oder so ... So ein Problem wie das mit WM_QUIT reizt mich einfach delphitechnisch, allein durch die Beschäftigung in diesem Zusammenhang mit den Systemnachrichten hab ich viel über WinAPI, WndProc und so gelernt
Johannes Maier
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#6

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 16:06
Nein, leider nicht.
Du musst wohl was anderes als WM_QUIT senden, vielleicht, .. WM_PRINT?
  Mit Zitat antworten Zitat
Johannes Maier

Registriert seit: 3. Sep 2004
25 Beiträge
 
Delphi 7 Professional
 
#7

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 16:29
Mich hatte einfach Nachrichtenbehandlung, die message-Direktive usw. interessiert, dann hab ich im Delphi-Forum ein paar Beiträge dazu gelesen, und dann was pber SendMessage, PostMessage und WndProc
Als ich dann rausgefunden hab, wie man SendMessage-Nachrichten behandelt, und dass man mit der gleichen Methode keine PostMessage-Nachrichten behandeln kann, hab ich nach einer Lösung für dieses problem gesucht usw.
Dann hab ich herausgefunden, dass dies bei WM_QUIT nicht funktioniert und wollte schauen, ob es dafür auch eine solche Lösung gibt, dass die Message anders behandelt wird, aber dem war wohl nicht so ...

Danke dann mal
Johannes Maier
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 17:39
Noch mal im Klartext: MSDN-Library durchsuchenWM_QUIT beendet die MessageLoop deines Fensters>
Delphi-Quellcode:
while GetMessage(msg,0,0,0) do
  begin
    TranslateMessage(msg);
    DispatchMessage(msg);
  end;
Das heißt TranslateMessage bzw. in diesem Fall das wichtigere DispatchMessage wird nicht mehr aufgerufen und somit kann DispatchMessage die Nachricht nicht an die Zuständige Fensterprozedur weiterleiten. Du wirst also nie eine WM_QUIT zu sehen bekommen.

Wozu brauchst du denn das überhaupt?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#9

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 3. Sep 2004, 18:02
Zitat von Johannes Maier:
Mich hatte einfach Nachrichtenbehandlung, die message-Direktive usw. interessiert, dann hab ich im Delphi-Forum ein paar Beiträge dazu gelesen, und dann was pber SendMessage, PostMessage und WndProc
  Mit Zitat antworten Zitat
Golze

Registriert seit: 26. Aug 2004
Ort: Berlin
32 Beiträge
 
Delphi 5 Enterprise
 
#10

Re: Problem bei der Verarbeitung von Systemnachrichten

  Alt 4. Sep 2004, 10:45
Hallo Johannes,
ich habe mal bei mir im Archiv nachgeschaut und ein kleines aber feines Testprogramm rausgebuddelt. Wenn du das Programm verstanden hast, versteht du auch die Hierarchie der Message-Verarbeitung durch die VCL. Das WM_QUIT-Ereingis wird innerhalb der VLC im Objekt TApplication einfach auf das Property Terminated umgesetzt . Erhält dein Programm diese Nachricht, ist Application.Terminated immer True. Generell kannst du aber die Auswirkungen des Ereignisses nicht aufheben - also das Beenden des Programms. Du kannst es aber - siehe Beispielprogramm - abfangen und noch letzte arbeiten ganz in Ruhe durchführen lassen. Das Testprogramm ist als Anhang ebenfalls dabei.
Grüße Kay

Delphi-Quellcode:
unit Main;
interface
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls;

const
  MyMesage = {WM_QUIT} WM_USER; //test also WM_USER message to see the full functionality

type
  TMainForm = class(TForm)
    SendBtn: TButton;
    PostBtn: TButton;
    procedure SendBtnClick(Sender: TObject);
    procedure PostBtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    OldWndProc: Pointer;
    WndProcPtr: Pointer;
    procedure HandleAppIdleState(Sender: TObject; var Done: Boolean);
    procedure WndMethod(var Msg: TMessage);
    procedure HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
    procedure AppDeactivate(Sender: TObject);
  end;

var
  MainForm: TMainForm;

implementation
{$R *.DFM}

var
  WProc: Pointer;

function NewWndProc(Handle: hWnd; Msg, wParam, lParam: Longint): Longint; stdcall;
{Description:
  This is a Win32 API-level window procedure. It handles the messages
  received by the Application window.
}

begin
  {If it's our user-defined message, then alert the user.
  }

  if Msg = MyMesage then
    MessageBox(0, PChar(Format('Message seen by NewWndProc! Value is: %u', [Msg])),
                  PChar('Check WM_QUIT Message'), MB_OK);
  {Pass message on to old window procedure
  }

  Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;

procedure TMainForm.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);
{Description:
OnMessage handler for Application object.
}

begin
  {if it's the user-defined message, then alert the user.
  }

  if Msg.Message = MyMesage then
    MessageBox(0, PChar(Format('Message seen by OnMessage! Value is: %u', [Msg.Message])),
                  PChar('Check WM_QUIT Message'), MB_OK);
end;

procedure TMainForm.WndMethod(var Msg: TMessage);
begin
  {if it's the user-defined message, then alert the user.
  }

  if Msg.Msg = MyMesage then
    MessageBox(0, PChar(Format('Message seen by WndMethod! Value is: %u', [Msg.Msg])),
                  PChar('Check WM_QUIT Message'), MB_OK);
  {Pass message on to old window procedure.
  }

  with Msg do
    Result := CallWindowProc(OldWndProc, Application.Handle, Msg, wParam, lParam);
end;

procedure TMainForm.HandleAppIdleState(Sender: TObject; var Done: Boolean);
var Msg: TMsg;
begin
  {Get the message from the queue.
  }

  if PeekMessage(Msg, 0, 0, 0, PM_NoREMOVE) then
  begin
    if Msg.Message = MyMesage then
      MessageBox(0, PChar(Format('Message seen by HandleAppIdleState! Value is: %u', [Msg.Message])),
                    PChar('Check WM_QUIT Message'), MB_OK);
  end;
end;

procedure TMainForm.AppDeactivate(Sender: TObject);
begin
  if Application.Terminated then
    MessageBox(0, PChar('Message seen by AppDeactivate! WM_QUIT'),
                  PChar('Check WM_QUIT Message'), MB_OK);
end;

procedure TMainForm.SendBtnClick(Sender: TObject);
begin
  {The SendMessage function sends the specified message to a window or windows. The
  function calls the window procedure for the specified window and does not return
  until the window procedure has processed the message. The PostMessage function, in
  contrast, posts a message to a thread's message queue and returns immediately.
  }

  SendMessage(Application.Handle, MyMesage {WM_QUIT}, 0, 0);
end;

procedure TMainForm.PostBtnClick(Sender: TObject);
begin
  {The PostMessage function places (posts) a message in the message queue associated
  with the thread that created the specified window and then returns without waiting
  for the thread to process the message.
  }

  PostMessage(Application.Handle, MyMesage {WM_QUIT}, 0, 0);
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  Application.OnDeactivate := AppDeactivate;
  Application.OnIdle := HandleAppIdleState;
  Application.OnMessage := HandleAppMessage; // set OnMessage handler
  WndProcPtr := MakeObjectInstance(WndMethod); // make window proc
  {Set window procedure of application window.
  }

  OldWndProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC,
                                      Integer(WndProcPtr)));
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  if Application.Terminated then
    MessageBox(0, PChar('Message seen by FormDestroy! WM_QUIT'),
                  PChar('Check WM_QUIT Message'), MB_OK);
  {Restore old window procedure for Application window
  }

  SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(OldWndProc));
  {Free our user-created window procedure
  }

  FreeObjectInstance(WndProcPtr);
end;

initialization
  {Set window procedure of Application window.
  }

  WProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC,
                                 Integer(@NewWndProc)));
end.
Angehängte Dateien
Dateityp: zip vclmessagehandling_702.zip (3,0 KB, 22x aufgerufen)
Kay Golze
Wo Gold ist, muß es auch glänzen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:48 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