tags:

views:

215

answers:

4

I am currently working on a win32 GUI app that does most of its work in the window thread.
This thread can sometimes be blocked since it runs a script engine that can be suspended by an external script debugger (another process). This is not a problem most of the time as it is expected behavior.
However, if the user tries to close the window, the app obviously becomes unresponsive and you get the "This application is not responding..." dialog.
My plan was to periodically call back from the "suspend code" to the app and have it do PeekMessage for WM_CLOSE, and if so, terminate the debugger. Unfortunately, from what I can understand, WM_CLOSE it sent directly to the wndproc.

Is there some other way that I could detect that the user wants to close the window, short of redesigning the app which is not an option?
For example, is there some other message that can be checked for with PeekMessage?

A: 

If you are debugging, wouldn't that mean the user was debugging? Why would they be surprised that the app was then "not responding"? Anyway, you have control of the window procedure for the window, so why not just watch for the WM_CLOSE message in there? It is your window?

1800 INFORMATION
The user is debugging a script that is executed in the engine contained by the app in question.If I'm not mistaking, the window procedure is called on the window thread, which is blocked.
Niklas
+1  A: 

I guess you can keep handling your WM_ CLOSE message in the wndproc, and when you receive it you call PostQuitMessage(), which in turn will generate a WM_ QUIT message that in turn will be read by GetMessage()/PeekMessage().

If your window thread is completely blocked, you're out of luck. You have a few options. The thread must be able to periodically do PeekMessage() while in "script engine mode".

while (IsScripting()) {
    ScriptEngineTimeSlice();
    while (PeekMessage( .. )) {
        TranslateMessage( .. );
        DispatchMessage( .. ); // <-- wnd procedure will be called
        // ..
    }
}

This is probabably old news for you, since you already are aware of this. But if you somehow can't give the UI thread a break, there is no way to solve this. If the thread is blocked, it's blocked.

Magnus Skog
The problem is that the wndproc is called on the window thread, which is blocked in the scenario at hand.
Niklas
How is the connection made between this script engine and your app? Is the main thread merely making a function call into a library or starting a new process that it's waiting for to finish?
Magnus Skog
The app drives the script engine on its window thread, hence the problem.
Niklas
Not the answer you were looking for. (Hur som helst, lycka till !)
Magnus Skog
+1  A: 

How about this: periodically spin a message loop to dispatch any messages on the message queue (that'll cause mouse/input messages to be handled which will generate the WM_CLOSE). In your app's main window set a flag when WM_CLOSE is received and check that flag after spinning the loop.

Simplest case of spinning a message loop to flush any pending messages would be:

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

though your app frame work may already have functions to do this. Hope this helps.

cantabilesoftware
It has, and the problem is that if I call it, it may cause another call into the script engine which is already suspended... It's a mess, but I'm unfortunately hindered from redesigning the app.
Niklas
+1  A: 

Would you consider adding another thread redesigning the application? It certainly would make your life much easier! Just let the Gui do all the Gui stuff and run it's message loop and do all the hard work in another thread. If the user wants to quit the application, present him a nice OK/Cancel message and suspend/abort the "worker thread" accordingly. Handling two separate tasks in this one thread - with all the workarounds - will make things way more messier than it has to be. Good luck!

merkuro
That is obviously the best solution, but unfortunately not what I asked. See "Is there some other way that I could detect that the user wants to close the window, short of redesigning the app which is not an option?".
Niklas