0

I have to catch WM_QUIT message in WPF but there is a problem.

IntPtr windowHandle = (new WindowInteropHelper(this)).Handle;
HwndSource src = HwndSource.FromHwnd(windowHandle);
src.AddHook(new HwndSourceHook(WndProc));

WndProc works fine and catch all messages except WM_QUIT.

Msdn says:

The WM_QUIT message is not associated with a window and therefore will never be received through a window's window procedure. It is retrieved only by the GetMessage or PeekMessage functions.

Is there any way to catch this message in WPF? Maybe with ComponentDispatcher?

There is also: http://www.pinvoke.net/default.aspx/user32.getmessage

Which can be used in C# environment.

Any help would be welcome.

Alex K.
  • 171,639
  • 30
  • 264
  • 288
Igor
  • 11
  • 5
  • Perhaps if you explain why you want to do this a native alternative can be suggested. – Alex K. Sep 22 '16 at 16:01
  • As you found out, that message really isn't a message. Think of it as a flag, that instructs the message retrieval functions to synthesize an object that has a `WM_QUIT` message ID. [Why is there a special PostQuitMessage function?](https://blogs.msdn.microsoft.com/oldnewthing/20051104-33/?p=33453) explains some of the details. It is **very** unlikely, that your proposed solution will get you anywhere. Maybe you should ask about your problem instead. – IInspectable Sep 22 '16 at 16:07
  • I want to shutdown my app gracefully. C++ program that sends wm_quit cant be changed . – Igor Sep 22 '16 at 16:08
  • Your main windows Closing event does not get raised? – Alex K. Sep 22 '16 at 16:12
  • Thing is that i have splash screen and if c++ app post wm_quit while it splash still active it close splash but main window continue it is responsive but without graphic – Igor Sep 22 '16 at 16:20
  • 1
    The obvious solution would then be to fix **that** bug, instead of attempting a highly intrusive solution, only to keep going with a buggy implementation. And by *"bug"* I am referring to an external program sending a `WM_QUIT` message. I already linked you to information, why `WM_QUIT` is special, and why faking it is wrong. – IInspectable Sep 22 '16 at 16:22
  • Once after splash screen goes away works good. App close when wm_quit is posted – Igor Sep 22 '16 at 16:24
  • So the c++ should not post that message? What do you mean by faking it? – Igor Sep 22 '16 at 16:27
  • Stop posting that message. Fix the real problem. – David Heffernan Sep 22 '16 at 16:36
  • Why is the C++ program posting that message? That message is not allowed to be posted; if one program wants to ask another program to close, it will need to do so in a cooperative way (or if all else fails, with WM_CLOSE, which is a different message that is equivalent to clicking the Close button on the titlebar and would generate a Closing event in your WPF window). – andlabs Sep 22 '16 at 16:50
  • So the real problem is that message and cannot be handled properly? – Igor Sep 22 '16 at 16:51
  • No, the **real** problem is, that you aren't following the contract. The only way to generate a `WM_QUIT` message is by calling `PostQuitMessage`. Everything else is a bug. You need to fix that bug. Your WPF application has no trouble responding to a **real** `WM_QUIT` message. – IInspectable Sep 22 '16 at 16:52
  • Problem is that i dont work on that c++ app i have nothing to do with. its made by my fellow at work . He said that they had no problem sending this message to win forms. Wpf is responding on that message but i cannot get this message in wpf it just terminate – Igor Sep 22 '16 at 17:05
  • And when splash window is active mainwindow is hidden and that hidden window do not get closed if that message is send when splash is still active – Igor Sep 22 '16 at 17:08
  • If wpf has no problem responding to wm_quit how to get that message in code behind or it just call window close method? – Igor Sep 22 '16 at 17:10
  • Their code is being lucky; they are still breaking the rules, and Microsoft are well within their power to make trying to post WM_QUIT manually do nothing at some point in the future. They should fix their code to use WM_CLOSE on a window to request a close. Then, you would just need to handle the Closing event in WPF. Your code does not need to be changed; theirs does. If you can't convince them to do it, convince your bosses to force them to using the documentation on MSDN and The Old New Thing that has been linked here already and may be linked here by others later. – andlabs Sep 22 '16 at 17:21
  • So the wm_quit should not be used at all? – Igor Sep 22 '16 at 17:58
  • I ment that MV_QUIT can be used for certain examples, but not for closing apps gracefully. – Igor Sep 22 '16 at 18:33
  • No. You'll never even get WM_QUIT; in a traditional Windows message pump (which WPF uses internally), the presence of a WM_QUIT is indicated by a special return value from the message pump's "get next message" functions that says "okay, the message loop is over; time to go home". And even if you did get a WM_QUIT, it would not have an associated window handle. – andlabs Sep 22 '16 at 18:56
  • Aha this is kind a wpf thing? – Igor Sep 22 '16 at 19:11
  • It posible with winforms? – Igor Sep 22 '16 at 19:36
  • You are inverting history. All of this is explained by the rules of the Windows API. Since both Windows Forms, as well as WPF re-use the available infrastructure, those rules apply to those frameworks just as much. In other words: Sending a `WM_QUIT` message is meaningless for any application, regardless of the framework it uses. – IInspectable Sep 22 '16 at 20:36
  • But what about componentdispatcher https://msdn.microsoft.com/en-us/library/aa348549(v=vs.110).aspx – Igor Sep 22 '16 at 20:49
  • In combination of that: http://www.pinvoke.net/default.aspx/user32.getmessage – Igor Sep 22 '16 at 20:51
  • ThreadFilterMessage and ThreadPreprocessMessage events follow the standard rules for delegate invocations. Delegates are invoked in an unspecified order, and all delegates are invoked even if the first one marks the message as handled. – Igor Sep 22 '16 at 20:56
  • Why don't you just solve the problem instead of fixating on your bogus solution – David Heffernan Sep 22 '16 at 22:49
  • Get your coworkers to ask if they're doing it right on here then, if they're overruling you and forcing you to do something you literally cannot do. – andlabs Sep 23 '16 at 02:46
  • If your co-workers need a test-case, have them launch notepad.exe, gather it's main window handle using Spy++, and write a simple application that sends a `WM_QUIT` message to it. Closely observe, that this has no effect at all. – IInspectable Sep 23 '16 at 09:32

0 Answers0