PDA

View Full Version : Creating a Screen Saver for Windows



spud
27th March 2008, 17:41
Hi everybody,
I've seen this theme discussed before but I never found a complete solution, so I wrote one myself and plan to put it on the wiki. There is just one little kink to be worked out first.

A windows screen saver is just an exe renamed to .scr, which can be started in three modes, depending on the command line flags:

"-c" Configuration mode: The Application should pop up a config dialog, save changed properties to the registry and quit.
"-s" Screen saver mode: The Application should start in Full screen.
"-p XXXX" Preview mode: The Application should start as a child window to the "Windows Display Properties" dialog. The window ID is given as a second argument.

As could be expected I have no problems with the first two modes; the third mode is giving me a headache, though.
here is the relevant code:


...
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

// parse the commandline:
...

ScreenSaverWidget* widget = new ScreenSaverWidget;
widget->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(widget, SIGNAL(destroyed()), &app, SLOT(quit()));
switch(mode)
{
case ConfigurationMode:
configure();
return 0;

case FullScreenMode:
new ScreenSaverEventFilter(widget);
widget->showFullScreen();
break;

case PreviewMode:
{
widget->setWindowFlags(Qt::FramelessWindowHint|Qt::SubWind ow);
::SetParent(widget->winId(), parent);
RECT parentRect;
::GetClientRect(parent, &parentRect);
widget->move(0,0);
widget->resize(parentRect.right, parentRect.bottom);
widget->show();
}
}
return app.exec();
}


The good thing about the code above is that it is unobtrusive. I.e. you can replace ScreenSaverWidget with any other widget, without having to change its code.
In full screen mode I install an event filter that intercepts mouse movements and key presses.
In preview mode I reparent the widget using win32 API calls and that's where something goes wrong. The widget shows up allright, but it doesn't seem to be embedded properly. closeEvent() and the dtor never gets called when I close the dialog and the application never shuts down properly.

I'm hoping some one has an idea what I have to do.

I attach the complete code. To test it you have to right click on ScreenSaver.scr and select "install".

thanks

crusader_vie
2nd November 2011, 15:58
try this


...
int main(int argc, char* argv[])
{
QApplication app(argc, argv);

// parse the commandline:
...

ScreenSaverWidget* widget = new ScreenSaverWidget;
widget->setAttribute(Qt::WA_DeleteOnClose);
QObject::connect(widget, SIGNAL(destroyed()), &app, SLOT(quit()));
switch(mode)
{
case ConfigurationMode:
configure();
return 0;

case FullScreenMode:
new ScreenSaverEventFilter(widget);
widget->showFullScreen();
return app.exec();

case PreviewMode:
{
widget->setWindowFlags(Qt::FramelessWindowHint|Qt::SubWind ow);
::SetParent(widget->winId(), parent);
RECT parentRect;
::GetClientRect(parent, &parentRect);
widget->move(0,0);
widget->resize(parentRect.right, parentRect.bottom);
widget->show();
}
}

}