Problem 1: String Conversions
Your primary problem is that you are attempting to use LPCWSTR
(a const wchar_t *
) and const char *
interchangeably. I see a number of issues in your source, in particular:
- You start with
const char * image_name
.
- You then cast it to a
LPCWSTR
to pass to SetWallpaper
. This basically guarantees that SetWallpaper
will fail, as desktop->SetWallpaper
is not able to handle non wide-character strings.
- You then cast it back to a
const char *
to pass to stat()
via exists()
. This should work in your situation (since the original string really is a char *
) but isn't correct because your string parameter to SetWallpaper
is supposedly a proper LPCWSTR
.
You need to pick a string format (wide-character vs. what Windows terms "ANSI") and stick to that format, using consistent APIs throughout.
The easiest option is probably just to leave most of your code untouched, but modify SetWallpaper
to take a const char *
and convert to a wide-character string when needed (for this you can use mbstowcs
). So, for example:
void SetWallpaper(const char * file){ // <- Use a const char* parameter.
...
// Convert to a wide-character string to pass to COM:
wchar_t wcfile[MAX_PATH + 1];
mbstowcs(wcfile, file, sizeof(wcfile) / sizeof(wchar_t));
// Pass the converted wide-character string:
desktop->SetWallpaper(wcfile, 0);
...
}
The other option would be to use wide-character strings throughout, i.e.:
LPCWSTR image_name = L"button_out.gif";
- Modify
exists()
to take a LPCWSTR
and use _wstat()
instead.
- Use wide-character versions of all other API functions.
However, I am unsure how that would interact with the ImageMagick API, which may not have wide-character support. So it's up to you. Choose whatever approach is the easiest to implement but make sure you are consistent. The general rule is do not cast between LPCWSTR
and const char *
; if you are ever in a situation where you need to change one to the other, you cannot cast, you must convert (via mbstowcs
or wcstombs
).
Problem 2: SetWallpaper default directory is not current working directory
At this point, your string usage will be consistent. Now that you have that problem ironed out, if SetWallpaper
fails while exists()
does not, then SetWallpaper
is not looking where you think it is. As you discovered in your comment, SetWallpaper
looks in the desktop by default. In this case, while I have not tested it, you may be able to work around this by passing an absolute path to SetWallpaper
. For this, you can use GetFullPathName
to determine the absolute file name given your relative path. Remember to be consistent with your string types, though.
Also, if stat()
continues to fail, then that problem is either that your working directory is not what you think it is, or your filename is not what you think it is. To that end you will want to perform the following tests:
- Print the current working directory at the point you check for the files existence, verify it is correct.
- Print the filename when you check for its existence, verify it is correct.
You should be good to go once you work all the above issues out.