Setting wallpaper on windows
I've googled around a bit to try to find out how to set the desktop background in windows. The following is code that looks like it should work, but for some reason it won't.
Code:
#include "wallpapr.h"
#include <QSettings>
#include <QVariant>
#ifdef WIN32
#include <windows.h>
Wallpapr
::Wallpapr(QWidget *parent
){
//ui.setupUi(this);
// String *path = "C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp";
QString *path
= new QString("C:\\Documents and Settings\\Marius\\Local Settings\\Application Data\\Microsoft\\Wallpaper1.bmp");
//C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//ui.oldWallpaper->setText(settings->value("Wallpaper").toString());
settings
->setValue
("Wallpaper",
QVariant(*path
));
//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp"); //settings->setValue("ConvertedWallpaper", QVariant(*path));//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//settings->setValue("OriginalWallpaper", QVariant(*path));//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//ui.tempWallpaper->setText(settings->value("Wallpaper").toString());
SystemParametersInfo(SPI_SETDESKWALLPAPER, 1, path, SPIF_SENDWININICHANGE);
//ui.newWallpaper->setText(settings->value("Wallpaper").toString());
}
Wallpapr::~Wallpapr()
{
}
#endif
It changes the registry values, but only removes the current wallpaper. The desktop is a clear color after running the program.
Anyone know how I could make it work?
Re: Setting wallpaper on windows
I doubt the WinAPI function takes a pointer to a QString. Are you sure this is correct?
Re: Setting wallpaper on windows
Well, it needs a pointer at least. And I thought QString was a subclass of String anyways.
edit: I tried with a char pointer instead, but it didn't work either.
Code:
#ifdef WIN32
#include <windows.h>
Wallpapr
::Wallpapr(QWidget *parent
){
ui.setupUi(this);
char *path = "C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp";
// QString *path = new QString("C:\\Documents and Settings\\Marius\\Local Settings\\Application Data\\Microsoft\\Wallpaper1.bmp");
//C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//ui.oldWallpaper->setText(settings->value("Wallpaper").toString());
settings
->setValue
("Wallpaper",
QString(path
));
//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp"); //settings->setValue("ConvertedWallpaper", QString(path));//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//settings->setValue("OriginalWallpaper", QVariant(*path));//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
//ui.tempWallpaper->setText(settings->value("Wallpaper").toString());
SystemParametersInfo(SPI_SETDESKWALLPAPER, 1, path, 0);//SPIF_SENDWININICHANGE);
//ui.newWallpaper->setText(settings->value("Wallpaper").toString());
}
Wallpapr::~Wallpapr()
{
}
#endif
[Second edit] Is there a way to run a dll file from a qt program? According to this article there is a way to do it in a batch file. That means it should be a way to do it in c++ too.
Re: Setting wallpaper on windows
Quote:
Originally Posted by
ihoss
Well, it needs a pointer at least.
But probably not any pointer. Did you read the function's docs at msdn?
Quote:
And I thought QString was a subclass of String anyways.
You were wrong. And char* is not a subclass of String as well (nor the other way round).
Re: Setting wallpaper on windows
I tried making a string from the char pointer. It doesn't change the current wallpaper, but it doesn't remove the previous one either. The function returns false. But if I set the second parameter to NULL it returns true. Nothing happens on the desktop though.
Code:
#include "wallpapr.h"
#include <QSettings>
#include <QVariant>
#include <QDirModel>
#include <QFileDialog>
#include <QPixmap>
#include <iostream>
#include <stdio.h>
#include <string>
#ifdef WIN32
//#include <winuser.h>
#include <Windows.h>
using namespace std;
Wallpapr
::Wallpapr(QWidget *parent
){
ui.setupUi(this);
char *path = "C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp";
// QString *path = new QString("C:\\Documents and Settings\\Marius\\Local Settings\\Application Data\\Microsoft\\Wallpaper1.bmp");
//C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp");
QSettings *settings
= new QSettings(WALLPAPER,
//"HKEY_CURRENT_USER\\Control Panel\\Desktop", //ui.oldWallpaper->setText(settings->value("Wallpaper").toString());
settings
->setValue
("Wallpaper",
QString(path
));
//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp"); settings
->setValue
("ConvertedWallpaper",
QString(path
));
//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp"); settings
->setValue
("OriginalWallpaper",
QString(path
));
//"C:\\Documents and Settings\\All Users\\Documents\\My Pictures\\Sample Pictures\\Sunset.bmp"); //ui.tempWallpaper->setText(settings->value("Wallpaper").toString());
string *pathStr // = new string();
= new string(path);
//string *wp = new string();
//SystemParametersInfo(SPI_GETDESKWALLPAPER, 100, wp, 0);
//qdebug()<<wp;
bool ret = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,
pathStr,
//NULL,
//0);
//SPIF_SENDCHANGE);
//SPIF_SENDWININICHANGE);
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
ui.newWallpaper->setText(ret ? "true" : "false");
}
Wallpapr::~Wallpapr()
{
}
#endif
Re: Setting wallpaper on windows
Did you read the function's description at msdn?
Re: Setting wallpaper on windows
Re: Setting wallpaper on windows
But have you identified your problem? Does the registry change when you use the function or not? If you relogin, do you see the old or the new wallpaper?
Re: Setting wallpaper on windows
Calling the function alone seems to have no effect; it doesn't change the current wallpaper, nor the wallpaper when I log off and log on again. The function also returns false. Changing the registry files only changes the wallpaper when I log off and log on again, but not immediately.
I tried adding this to see what error I got, but all it returned was T.
Code:
char* str = NULL; // function allocates the mem with LocalAlloc(), used with LocalFree()
int msg_ret = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | // let the function alloc string mem
FORMAT_MESSAGE_FROM_SYSTEM | // use system message and not a passed one
FORMAT_MESSAGE_IGNORE_INSERTS, // ignore and "inserts"
NULL,
GetLastError(), // get the error
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(WCHAR*)&str,
0,
NULL);
printf("The error is: %s", str);
Re: Setting wallpaper on windows
Ok, I took a few steps back and made a single c++ file that only changes the wallpaper, no GUI.
Code:
#include <iostream>
#include <stdio.h>
#include <string>
#include <Windows.h>
using namespace std;
int main () {
char *path = "C:\\WINDOWS\\Web\\Wallpaper\\Windows XP.jpg";
string *pathStr = new string(path);
bool ret = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,
pathStr,
//NULL,
//0);
//SPIF_SENDCHANGE);
//SPIF_SENDWININICHANGE);
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
cout<<"the function returned "<<(ret ? "true" : "false");
char* str = NULL; // function allocates the mem with LocalAlloc(), used with LocalFree()
int msg_ret = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | // let the function alloc string mem
FORMAT_MESSAGE_FROM_SYSTEM | // use system message and not a passed one
FORMAT_MESSAGE_IGNORE_INSERTS, // ignore and "inserts"
NULL,
GetLastError(), // get the error
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(CHAR*)&str,
0,
NULL);
cout<<"\n"<<str;
cout<<"\n"<<path;
return 0;
}
at it returns
Code:
the function returned false
The system cannot find the file specified.
C:\WINDOWS\Web\Wallpaper\Windows XP.jpg
But the file exists. I have also tried with bmp files, getting the same error message.
Re: Setting wallpaper on windows
As far as I know you can't set jpeg files as wallpapers this way. But if it doesn't work with BMP files, then something else has to be wrong. Try a simpler path such as C:\xyz.bmp
Re: Setting wallpaper on windows
Nope, not C:\Bliss.bmp or Bliss.bmp in the same folder. It could be that the functon expects something else than a char pointer.
Re: Setting wallpaper on windows
It might require a wchar pointer. I suggest using this function first to query for the existing wallpaper. This way you'll be able to see how the path is stored in the buffer you provide.
Re: Setting wallpaper on windows
Code:
#include <iostream>
#include <stdio.h>
#include <string>
#include <Windows.h>
using namespace std;
int main () {
char *path = "C:\\Bliss.bmp";
bool ret = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0,
path,
//NULL,
//0);
//SPIF_SENDCHANGE);
//SPIF_SENDWININICHANGE);
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
cout<<"the function returned "<<(ret ? "true" : "false");
char* str = NULL; // function allocates the mem with LocalAlloc(), used with LocalFree()
int msg_ret = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | // let the function alloc string mem
FORMAT_MESSAGE_FROM_SYSTEM | // use system message and not a passed one
FORMAT_MESSAGE_IGNORE_INSERTS, // ignore and "inserts"
NULL,
GetLastError(), // get the error
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(CHAR*)&str,
0,
NULL);
cout<<"\n"<<str;
cout<<"\n"<<path;
return 0;
}
That code actually works! Great!
But it does not work in QT.
Re: Setting wallpaper on windows
What do you mean "in Qt"? There is no "in Qt" :) The only problem that might arise is that some macro is included that influences the behaviour of something else, but this is not really a problem with Qt. Reordering includes might help in such situation.
Re: Setting wallpaper on windows
Well, it works in its own little cpp file, but when I try to include it in the QT project, it won't work. I have tried to rearrange the includes, but it has no effects. I've also set the namespace to std, but it does not seem to be required to make the little cpp compile.
edit: There is one strange thing though. In the little cpp i have to use CHAR as the 5th argument in the FormatMessage function, but in the "qt" program i have to use WCHAR. That is kinda strange when I include the same files and compile it with the same compiler.
Re: Setting wallpaper on windows
I tried to include the little cpp in the main project and just call the function from the application. It didn't work. I've also made sure both are compiled with mingw, and it only works when it is on its own.
Re: Setting wallpaper on windows
Use SystemParametersInfoA or convert your QString properly to a WCHAR array with QString::utf16().
Re: Setting wallpaper on windows
Wow, adding that A fixed the problem! Thanks a lot Christian. Thanks also to wysota for keeping dialog going :p
Re: Setting wallpaper on windows
Quote:
Originally Posted by
ChristianEhrlicher
Use SystemParametersInfoA or convert your QString properly to a WCHAR array with QString::utf16().
Thank's for this!
IT work's:
QString screenPath="C:\\screen.bmp";
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)screenPath.utf16(), SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE)