Autor |
Beitrag |
Johannes Maier
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Do 02.09.04 22:10
Hallo,
neue Frage -> neuer Thread -> dieser hier
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-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| 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 ShowMessage('WM_QUIT erhalten ...'); Handled := True; end; end; |
Damit sollte es doch eigentlich funktionieren, oder hab ich wieder was vergessen? 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.
_________________ MfG
Johannes ehem. jbmaier
Zuletzt bearbeitet von Johannes Maier am So 12.09.04 11:14, insgesamt 1-mal bearbeitet
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: Do 02.09.04 22:17
Wenn du die Message sowieso nur intern verwendest, kannst du dir doch eine Usermessage festlegen und musst nicht Windows-eigene Messages zweckentfremden. Oder spricht da was dagegen?
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Fr 03.09.04 06:41
Ja, denn ich möchte beim Verlassen des Programms noch was Wichtiges ausgeben  Da dies bei OnFormClose jedoch nicht funktioniert (ich weiß ja, dass dem Fenster WM_QUIT gesendet wird), muss ich diese Nachricht abfangen.
Sonst hätte ich es ja einfach per SendMessage machen können, aber leider ist es PostMessage  Und ich bekomme es nicht hin, diese abzufangen 
_________________ MfG
Johannes ehem. jbmaier
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.09.04 09:10
jbmaier hat folgendes geschrieben: | Ja, denn ich möchte beim Verlassen des Programms noch was Wichtiges ausgeben |
Aller letzte Möglichkeit was auszugeben, wäre noch vielleichet eine MessageBox im finalization Teil.
Zitat: | Und ich bekomme es nicht hin, diese abzufangen  |
Ja, ja. Das ist gar nicht so einfach. 
_________________ Ciao, Sprint.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 03.09.04 09:16
Schonmal OnCloseQuery probiert?
Da dort das Schließen des Fensters sogar noch verboten werden kann, müsste die Nachricht angezeigt werden können.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.09.04 09:35
jasocul hat folgendes geschrieben: | Schonmal OnCloseQuery probiert? |
OnCloseQuery hält keine WM_QUIT Nachricht auf.
_________________ Ciao, Sprint.
|
|
jasocul
      
Beiträge: 6393
Erhaltene Danke: 147
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 03.09.04 09:43
War ja auch nur 'ne Idee. Ich meinte mal in irgendeiner Doku gelesen zu haben, dass CloseQuery auch WindowsShutDown reagieren sollte. Daher nahm ich an, dass das auch bei WM_QUIT läuft.
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.09.04 09:51
Ich glaube da werden andere Nachrichten gesendet. In Form von WM_ENDSESSION und WM_QUERYENDSESSION.
_________________ Ciao, Sprint.
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Fr 03.09.04 12:40
Nicht vom Thema abkommen bitte
Weiß hier niemand eine Lösung für das Problem.
Meiner Denkweise nach muss diese Nachricht ja irgendwo ankommen, und dort muss man sie auch verarbeiten, damit das Programm weiß, was es zu tun hat.
So, hab jetzt durch Testen herausgefunden, dass man WM_CLOSE so abfangen kann (hab noch Handled := True und ShowMessage() vertauscht) ...
Bei WM_QUIT funktioniert der gleiche Code jedoch nicht
Wieso geht das nicht, und wie kann ich es bewerkstelligen, dass es doch funktioniert 
_________________ MfG
Johannes ehem. jbmaier
|
|
.Chef
      
Beiträge: 1112
|
Verfasst: Fr 03.09.04 14:13
Weiß nicht, ob es einen Unterschied macht, aber hast du schonmal probiert, die Message mit einer eigen Prozedur abzufangen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type TForm1 = class(TForm) private procedure wmquit(var msg: TWMQuit);message WM_QUIT; ... end;
...
procedure TForm1.wmquit(var msg: TWMQuit);message WM_QUIT; begin end; |
_________________ Die Antworten auf die 5 häufigsten Fragen:
1. Copy(), Pos(), Length() --- 2. DoubleBuffered:=True; --- 3. Application.ProcessMessages bzw. TThread --- 4. ShellExecute() --- 5. Keine Vergleiche von Real-Typen mit "="!
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Fr 03.09.04 14:19
Jep hab ich, aber diese Prozedur fängt dann nur mit SendMessage gesendet WM_QUIT's ab, nicht solche, die mit PostMessage geschickt werden ... leider ...
_________________ MfG
Johannes ehem. jbmaier
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.09.04 16:12
@jbmaier: Ich nehme mal an, das du auch der Verfasser von diesem Thread bist?
Reicht dir die Anwort, die du da bekommen hast?
_________________ Ciao, Sprint.
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Fr 03.09.04 16:39
Jep, danke für den Hinweis, jetzt hätte ich fast vergessen hier die Frage auf "gelöst" zu setzen, TY 
_________________ MfG
Johannes ehem. jbmaier
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Fr 03.09.04 17:15
jbmaier hat folgendes geschrieben: | Jep, danke für den Hinweis, jetzt hätte ich fast vergessen hier die Frage auf "gelöst" zu setzen, TY  |
Sprint hat folgendes geschrieben: | Ja, ja. Das ist gar nicht so einfach.  |
Falls dich das doch irgendwann nochmal interessieren sollte, dann kannst du ja nochmal fragen.
Edit: Ich will es dann mal nicht so spannend machen. Das Zauberwort heiß SetWindowsHookEx in Verbindung mit WH_GETMESSAGE.
_________________ Ciao, Sprint.
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Sa 04.09.04 14:33
Also meinst du jetzt damit, dass es doch möglich ist, WM_QUIT abzufangen?
Denn alle anderen (ausnahmslos denke ich, bei MSDN steht WM_QUIT sei die einzige Ausnahme) kann ich mit dem Quellcode ganz oben abfangen (bei Application.OnMessage). Bei mit SendMessage gesendeten Nachrichte geht es ganz einfach hiermit:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| type TForm1 = class(TForm) private public procedure WndProc(var Msg: TMessage); override; protected published end;
procedure WndProc(var Msg: TMessage); begin if Msg.Msg = WM_IRGENDWAS then ShowMessage('WM_IRGENDWAS kommt an ...'); end; |
bzw. hiermit:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TForm1 = class(TForm) private public procedure DoSomething(var Message: TMessage); message WM_IRGENDWAS; end; |
Aber was du sagst interessiert mich  Erzähl mal ein bisschen 
_________________ MfG
Johannes ehem. jbmaier
|
|
Sprint
      
Beiträge: 849
|
Verfasst: Sa 04.09.04 15:57
Johannes Maier hat folgendes geschrieben: | Also meinst du jetzt damit, dass es doch möglich ist, WM_QUIT abzufangen? |
Ja, du kannst die Nachricht WM_QUIT abfangen.
Warum du die Nachricht nicht mit deinem Quellcode abfangen kannst, hat dir Luckie doch schon gesagt.
Edit: Hab gerade gesehen, das du von Golze im dp Forum schon eine Lösung bekommen hast.
Ich will dir aber noch mal was anderes zeigen. Und zwar mit SetWindowsHookEx.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private procedure SetMsgHook; procedure Unhook; public end;
var Form1: TForm1;
implementation
{$R *.dfm}
var MsgHook: HHOOK;
function GetMsgProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; const S_MSG = 'Eine WM_QUIT Nachricht wird an dieses Programm geschickt.' + #13#10 + 'Soll die Nachricht verarbeitet werden?'; var Msg: PMsg; begin
if Code = HC_ACTION then begin
Msg := PMsg(lParam);
if Msg^.message = WM_QUIT then if Application.MessageBox(S_MSG, nil, MB_YESNO or MB_ICONINFORMATION) = IDNO then begin Msg^.message := WM_COMMAND; Msg.wParam := WM_NULL; Msg.lParam := 0; Result := 1; Exit; end;
end;
Result := CallNextHookEx(MsgHook, Code, wParam, lParam);
end;
procedure TForm1.SetMsgHook; begin
if MsgHook <> 0 then Exit;
MsgHook := SetWindowsHookEx(WH_GETMESSAGE, @GetMsgProc, 0, GetCurrentThreadId);
if MsgHook = 0 then Application.MessageBox(PChar(SysErrorMessage(GetLastError)), nil, MB_OK or MB_ICONQUESTION);
end;
procedure TForm1.Unhook; begin
if MsgHook = 0 then Exit;
UnhookWindowsHookEx(MsgHook); MsgHook := 0;
end;
procedure TForm1.FormCreate(Sender: TObject); begin
SetMsgHook; end;
procedure TForm1.FormDestroy(Sender: TObject); begin
Unhook;
end;
end. |
_________________ Ciao, Sprint.
|
|
Johannes Maier 
      
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Sa 04.09.04 17:34
Hmm ehrlich gesagt dachte ich, nur Golze hätte geantwortet (vor dir), und hab Luckies Beitrag erst bemerkt, weil du ihn hier erwähnt hast
Aber was er da gesagt hat, so hatte ich mir das auch vorgestellt, nur hätte ich niemals eine Umgehungsweise herausgefunden
Also eure Codes funktionieren, nur jetzt werde ich mich erst einmal mit dem "Warum" beschäftigen, im Moment interessiert mich alles rund um WinAPI  Dazu arbeite ich mich jetzt mal durch "DIE Win32-API-Tutorials" von Luckie
Vielen Dank nochmal, aber nächstes Mal werde ich schauen, dass ich Konversation nur noch in EINEM Forum führe ^^ denn das ständige Hin-Und-Her-Springen ist ziemlich anstrengend
Nebenbei: Wenn man mal fragen darf, was machst du beruflich und wie lange programmierst du schon?
_________________ MfG
Johannes ehem. jbmaier
|
|
Sprint
      
Beiträge: 849
|
Verfasst: So 05.09.04 01:03
Johannes Maier hat folgendes geschrieben: | Wenn man mal fragen darf, was machst du beruflich und wie lange programmierst du schon? |
Puh, das ist ja schon eine ganz schön persönliche Frage.
Ich werde im Januar 31 Jahre alt. Und meinen ersten Befehl habe ich Anfang der 80er Jahre geschrieben.
Ein Nachbarsjunge hatte Besuch aus Amerika und der hatte einen Sinclar ZX80 (ich glaub so hieß das Ding) mit.
Groß geworden bin ich aber auf einem Schneider CPC 6128. Da mein Bruder schon vorher einen VC20 und einen C64 hatte.
Was danach alles gekommen ist, weiß ich nicht mehr.
_________________ Ciao, Sprint.
|
|
|