0

My question is about windows messaging. I have 2 apps, communicating through WM_COPYDATA messages. Also in the first app, there are some application defined messages. The thing is, when WM_COPDATA message processed, also app defined message is send, and WM_COPYDATA processing stops and processing goes to my message. I understand it, when I add prinnt statements. (Actually, it doesn't effect program flow.)

Let me talk briefly about program flow. With every WM_COPYDATA message, one window is opened, and when it's opened a thread is created. This thread sleeps for 4 second, then sends MM_MY_MESSAGE with SendMessage(). So, at some point WM_COPYDATA and MM_MY_MESSAGE corresponds. What I expected was, after finishing one message it will continue with the next. But it happened differently.

case WM_COPYDATA:
    std::cout << "WM_COPYDATA started" << std::endl;
    //
    // do some stuff.
    //
    std::cout << "WM_COPYDATA finished" << std::endl;
    return 0;
case MM_MY_MESSAGE:
    std::cout << "--MM_MY_MESSAGE started--" << std::endl;
    //
    // do some stuff.
    //
    std::cout << "--MM_MY_MESSAGE finished--" << std::endl;
    return 0;

Output is:

WM_COPYDATA started
WM_COPYDATA finished
WM_COPYDATA started
WM_COPYDATA finished
WM_COPYDATA started
--MM_MY_MESSAGE started--
--MM_MY_MESSAGE finished--
WM_COPYDATA finished

How 'MM_MY_MESSAGE' prints come between WM_COPYDATA prints?

ilkerpyci
  • 99
  • 1
  • 9
  • 1
    The behavior you observe is called "reentrancy". The code helpfully represented with `do some stuff` yields - does something that "pumps" the message queue (retrieves and dispatches pending window messages). This includes, but not limited to, showing a modal dialog or a context menu; making an out-of-apartment COM call from a single-threaded apartment; and of course, calling things like `GetMessage` and `DispatchMessage` – Igor Tandetnik Feb 21 '16 at 20:28
  • 1
    Further to what @IgorTandetnik said, even calling `SendMessage` from within the message loop can cause this to happen. Without seeing the code you've omitted no one will be able to tell you exactly what's causing it. – Jonathan Potter Feb 21 '16 at 20:36
  • I have added some explanation. Can't show inside case statements because it's long, some of related code is inside another thread, etc. But there are no SendMessage() calls inside case statements. – ilkerpyci Feb 21 '16 at 20:55
  • @IgorTandetnik There are SetForegroundWindow() and BringWindowToTop() calls, inside WM_COPYDATA case. But parameter window is not this window (the window that processes MM_MY_MESSAGE). Can this effect my window's message loop, too? Also this window is message-only window. – ilkerpyci Feb 21 '16 at 21:19
  • 1
    Use the debugger to set a breakpoint on the `MM_MY_MESSAGE` case, and then follow the stack trace to see where the reentrancy came from. – Jonathan Potter Feb 21 '16 at 21:21
  • @JonathanPotter is it possible to avoid reentrancy? Because, my code is not safe for reentrancy and sequence of these messages might be important at same situations. – ilkerpyci Feb 21 '16 at 22:05
  • The best way to avoid reentrancy is to avoid yielding. Figure out where you do that, then cease and desist. – Igor Tandetnik Feb 21 '16 at 23:45
  • 1
    [BringWindowToTop](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632673.aspx) might call `SendMessage` as part of its implementation, opening a potential for re-entrancy. `SendMessage` dispatches inbound cross-thread sent messages. – IInspectable Feb 22 '16 at 14:38

0 Answers0