Shutdown blocked on XP


#1

I have a real nagging problem: I have an application (or really two, one with a hidden window) which have an icon in the taskbar, so it is kind of a background task (normally with no windows showing). When I try to shutdown windows, it blocks the OS from shutting down. If I exit the application prior to shutdown, everything works fine. Same thing with stand-by, i.e. it blocks the OS from going to stand-by state. I’ve tried handling the WM_POWERBROADCAST message (which is lacking in JUCE) which is required on XP (http://msdn.microsoft.com/en-us/library/aa373248(v=vs.85).aspx), but nooo… it still blocks the shutdown. I’m out of ideas… :frowning: help ?

/Rob


#2

When it’s trying to shut down, all the windows get a WM_CLOSE, but I guess if you don’t have any, you won’t get that. Perhaps the hidden message window needs to catch the WM_CLOSE, in juce_MessageWndProc… ?


#3

You’ll also get a WM_QUIT/WM_DESTROY message.
If you’re using a non GUI application, then it’ll default to break handler being called.
If you’re using a GUI application, and even if your windows is hidden, you’ll still get WM_QUIT / WM_DESTROY message.


#4

Thnx guys, but I don’t seem to get any broadcast message at all. The configuration is as follows: One non-juce message window for device change notifications (this one looks at WM_QUERYENDSESSION/WM_POWERBROADCAST/WM_CLOSE/WM_DESTROY, neither of which are received at log off/shutdown (but device notifications work fine) ) in one process, and one hidden juce window for the GUI in another process. None of these applications are closed during log off/shutdown. I’m going mad.

Edit: The message pump for the device change message window is run in its own thread. Maybe this is why the broadcast messages don’t arrive, i.e. the broadcasts are only sent to the main thread of an application ?


#5

I think the messages should get sent to all windows, but a thread can only dispatch events to windows that were created by that thread, so maybe it’s a thread/window mismatch?


#6

Nope, the msg-only window is created in the thread doing the message pumping, and that works fine… :frowning:


#7

A bit off topic, but could such API be added :

// This is used to retrieve screen saver state
bool Desktop::getScreenSaverState(int & timeout, bool & DPMSEnabled)
{
#ifdef JUCE_LINUX
       int interval = 0, preferBlank = 0, allowExp = 0;
       XGetScreenSaver(display, &timeout, &interval, &prefer_blank, &allow_exp);

       int tmp;
       if (DPMSQueryExtension(display, &tmp, &tmp)) 
       {
            CARD16 state;
            BOOL dpms;
            if (DPMSInfo(display, &state, &dpms) == TRUE) 
            {
                DPMSEnabled = dpms == TRUE;
                return state == TRUE;
             }
       }
       return timeout != 0;
#elif defined(JUCE_WINDOWS)
    BOOL enabled = FALSE;
    if (SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (PVOID)&enabled, 0))
         SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, (PVOID)&timeout, 0));
    return enabled == TRUE;
#else // Mac
    ???
#endif


// Set timeout to 0 to disable screen saver
Desktop::switchScreenSaver(const int timeout, bool useDPMS)
{
#ifdef JUCE_LINUX
       int tmp;
       if (useDPMS && DPMSQueryExtension(display, &tmp, &tmp)) 
       {
           if (timeout == 0) DPMSDisable(display);
           else DPMSEnable(display);
       }
       int _timeout = 0, interval = 0, preferBlank = 0, allowExp = 0;
       XGetScreenSaver(display, &_timeout, &interval, &prefer_blank, &allow_exp);
       XSetScreenSaver(display, timeout, interval, prefer_blank, allow_exposures); 
#elif defined JUCE_WINDOWS
         SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, timeout, NULL, 0));
         SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, timeout == 0 ? FALSE : TRUE, NULL, 0));
#else
#endif

}
// Called on shutdown request
Desktop::prepareShutdown()
{
    // Call your application overideable ::prepareShutdown()
}

#8

I think OS security will make it impossible to change the screen saver time-out on all platforms… You know there’s already a Desktop::setScreenSaverEnabled() call to temporarily stop it coming on, though?


#9

Yes, sort of. It doesn’t stop DPMS’ monitor-blanking from occuring (under Linux, I mean).
I know you might not have the right to change the screensaver/blanking timeout, but since I don’t check the return of the function, it’s not an issue in the code I’ve posted.

Ideally, I would have loved to detect when the monitor is blanked, and avoid doing intensive rendering in that case, but I couldn’t find any API for this detection anywhere (except by polling DPMSIsActive).


#10

Ok, there it is. Message only windows don’t receive broadcasts: http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only

Whether this will help my application shutdown properly, I don’t know. Still I have the juce based (invisible) window that doesn’t shutdown either… :frowning:


#11

Argh! It was a bug in MY code :oops:, now how could that happen ? :wink:


#12

Don’t worry, it happens to even the best of us… :slight_smile: