Jump to content
  • Advertisement
Sign in to follow this  
Endar

SystemParametersInfo - C/C++

This topic is 4567 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Okay, for starters, before we get going into my problem, here's something: in the MSDN 6 library, from cd, it says that if your call to SystemParametersInfo fails, to use GetLastError. Fine, no problem here. Then, for GetLastError, it directs you to FormatMessage to get a string describing the problem. And, in the FormatMessage info, it tell you to go back to GetLastError if it fails. Here's a question: what if you have problems making the FormatMessage function work? Can you really go back to GetLastError? I mean, you can call it, but how do you get useful information about the error without FormatMessage? </rant> Okay, now, onto my real problem. I'm attempting to use the SystemParametersInfo function to change the background. It's not going well.
if( !SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 
	"C:\\Documents and Settings\\Naim\\My Documents\\My Pictures\\naruto wallpapers\\Naruto022.jpg",
	SPIF_UPDATEINIFILE) ){

	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);

	printf(	"\n Error: Desktop wallpaper change failed."
			"\n Error message: %s"
			"\n", str);

	LocalFree(str);	// free the local mem allocated

	exit(1);
}



I got the SystemParametersInfo function from the other topic that was recently in the beginners forum, something about the program taking all the CPU time because he wasn't Sleep'ing it. Anyway, there's a random thing going on before the System.... call, but I've hardcoded everything until I get it going. For starters: yes, the file does exist in that directory, and it is a valid jpg file. Second, I get a strange string back from the FormatMessage function. Here's the total output:
 Error: Desktop wallpaper change failed.
 Error message: The operation completed successfully.
For an error message, that is honestly one of the least helpful I've seen. And, MSDN actually says:
Quote:
If the function fails, the return value is zero. To get extended error information, callGetLastError.
So, does anyone know how to use this function properly? Edit:: Also, I saved the file to a bmp and tried to use that as the filename, and, well it didn't work, the background stayed the same, but, the function was successful, it didn't enter the if.

Share this post


Link to post
Share on other sites
Advertisement
Ok, first of all, you probably want the fourth parameter to be SPIF_SENDCHANGE, not SPIF_UPDATEINIFILE. Currently, you're updating the stored setting, but nothing else is being notified of the change. Explorer won't look for a new background setting, you have to tell it it's changed. You'll find that the background will probably be applied when you restart currently. To have it happen instantly, change the fourth parameter to SPIF_SENDCHANGE.

Quote:
Here's a question: what if you have problems making the FormatMessage function work? Can you really go back to GetLastError? I mean, you can call it, but how do you get useful information about the error without FormatMessage?

GetLastError gives you the numerical identifier of the error. With the error number, you can just look it up in documentation. All FormatMessage does is look it up for you basically. System Error Codes.

Share this post


Link to post
Share on other sites
Correction: You want both SPIF_UPDATEINIFILE and SPIF_SENDCHANGE to be applied. Combine them using a binary or, like so:

SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);

Share this post


Link to post
Share on other sites
NOW we're cooking.

Okay, using both worked, as I can see it should, but I can only use it with bitmaps and not jpg's.

The background that I selected from the desktop properties was a jpg, so, why won't it work like this?

Share this post


Link to post
Share on other sites
Images that are not BMP (JPG, GIF...) will be converted to a temporary bitmap when you're selecting it from Display Properties, and this feature is functional when Active Desktop is activated. When you set the wallpaper using SystemParametersInfo (), the Active Desktop configurations (probably - I'm not sure about its underlying mechanism) remains unchanged, so calling SystemParameterInfos () with an image of type other than bitmap won't work (you'll see a black background instead).

Disabling Active Desktop will also disable the ability to select a JPG image in Display Properties.

Hth.

Share this post


Link to post
Share on other sites
That was quick! Thanks.


Edit:: Okay, I'm having a little trouble using this. I get that I have to access it through an IActiveDesktop interface. But beyond that, not a lot of the MSDN stuff I'm looking at is making sense.

I'm including shlobj.h, which looks like it has everything I need, but whenever I try to use IActiveDesktop as a namespace or class name, it just complains that it doesn't exist.

Share this post


Link to post
Share on other sites
You need to #include <WinInet.h>, or define _WININET_, the ShlObj.h checks for availability of this symbol to declare some other methods, but these have nothing to do with SetWallpaper ().

I hope this little program will run smoothly:

#include <Windows.h>
#include <WinInet.h>
#include <ShlObj.h>

//Main window procedure WinMain
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iShowCmd)
{
CoInitialize (NULL) ;

HRESULT hr;
IActiveDesktop *pActiveDesktop;

//Create an instance of the Active Desktop
hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IActiveDesktop, (void**)&pActiveDesktop);

//Insert code to call the IActiveDesktop methods
LPCWSTR wcPath = L"Insert File Path Here" ;
if (pActiveDesktop -> SetWallpaper (wcPath, 0) != S_OK)
{
//The method has failed...
}

// Call the Release method
pActiveDesktop->Release();

CoUninitialize () ;

return 0 ;
}


There maybe something wrong though, I have no compiler to check right now...

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!