I'm trying to write an app to change the desktop wallpaper, but the registry entry I've found only works after a restart and the SystemParametersInfo API only works for .bmp. Has anyone found a way around this? I can't use GD to convert, because I'd have to include wrappers and TLBs and all that.. but surely there's some way to do it. >.
[help] Set Wallpaper To Non-.bmp
Well, you might want to tell us what registry entry doesn't work.
Have you tried this registry entry?HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\LastTheme
Hope this helps,
nightcrawler1089
That doesn't seem to change anything.. there is a Wallpaper value under HKEY_CURRENT_USER\Control Panel\Desktop, but it has to be a BMP. ![]()
Ripped from a change-wallpaper application I wrote for Pe8er / Lou:
#include <windows.h>
#include <gdiplus.h>
#include <shellapi.h>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
)
{
GdiplusStartupInput g_gdiplusStartupInput;
ULONG_PTR g_gdiplusToken;
GdiplusStartup(&g_gdiplusToken, &g_gdiplusStartupInput, NULL);
WCHAR* wCmd = GetCommandLineW();
int argc(0);
WCHAR** argv = CommandLineToArgvW(wCmd,&argc);
if(argc > 1)
{
Bitmap* bmp = new Bitmap(argv[1]);
Bitmap* bmp2 = (Bitmap*)(((Image*)bmp)->Clone());
delete bmp;
bmp = 0;
char path[MAX_PATH];
GetWindowsDirectory(path,MAX_PATH);
strcat(path,"\\louwall.bmp");
OLECHAR wPath[MAX_PATH];
MultiByteToWideChar(CP_OEMCP,0,path,-1,wPath,MAX_PATH);
CLSID encoderClsid = {0};
GetEncoderClsid(L"image/bmp",&encoderClsid);
bmp2->Save(wPath, &encoderClsid, 0);
delete bmp2;
bmp2 = 0;
HKEY key = {0};
RegOpenKeyEx(HKEY_CURRENT_USER,"Control Panel\\Desktop\\",0,KEY_ALL_ACCESS,&key);
const char wp[] = {'W','a','l','l','p','a','p','e','r','\0'};
RegSetValueEx(key,wp,0,REG_SZ,(BYTE*)path,strlen(&path[0])+1);
RegFlushKey(key);
RegCloseKey(key);
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(PVOID)path,SPIF_SENDWININICHANGE);
}
GlobalFree((HGLOBAL)wCmd);
GlobalFree((HGLOBAL)argv);
GdiplusShutdown(g_gdiplusToken);
return 0;
}
Don't ask me about the strange things, I was on drugs I think <_<
It has to be bmp if you don't have active desktop enabled.
Don't know for XP; but 98, ME, NT and 2000 asked the user if
he/she wanted to enable ActiveDesktop if you tried to switch to a non bmp.
There should be a different API to do it without reboot.
Thanks, Ave, but I'm not using C.. I'd compile that into a COM DLL that I could use, but I don't have a compiler and wouldn't know how anyways. 
Well, The C++ shouldn't be the problem. For except the Gdiplus calls, there are only WINAPI calls.
What languages are you using then?
BTW, the wallpaper has to be a BMP file. Windows automatically converts any other type it seems to support to a Bitmap and stores this file in the root of your user directory. It also uses a certain registrykey to store the filepath of the original one.
Yes, I know about the conversion thing and the registry entry linking to it, and the API call for setting the wallpaper.. it's just the converting-to-BMP part I have a problem with. It's a Kapsules VBScript widget, which of course can't do any of that stuff, but my idea was to use VB6 to make a small OCX that'd convert the image and apply it. Could you give me any help on the minimum specific API calls I'd have to use, and how to use them?
You can do a conversion DLL in VB6 that loads the following:
GIF
JPG/JPEG
TIFF
and saves it to a BMP file. Just use the LoadPicture / SavePicture methods.
However, PNGs and other image types later than 1994 won't do.
To come around the reboot problem,
SystemParametersInfo(SPI_SETDESKWALLPAPER,0,(PVOID)path,SPIF_SENDWININICHANGE);
from Ave's C++ post does the trick. A lot of web sites dedicated to VB programming show you how to use it - googling helps.
Unfortunately, the IActiveDesktop interface I was referring to is not accessible by VB and vbScript - its SetWallpaper method would handle all image types that Internet Explorer is capable of viewing (without the need of conversion), even plugged in image helpers like QuickTime would extend its functionality...
hth,
herd
Aqua-Soft Forums