3

i am currently learning C++ and want to change my desktop wallpaper. However i am getting this error above.

#include <string>
#include <iostream>
#include <Windows.h>

using namespace std; 

int main() {

LPWSTR test = L"C:\\Users\\user\\Pictures\\minion.png";

int result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 
test, SPIF_UPDATEINIFILE);


}

A value of type "Const wchar_t*" cannot be used to initialize an entity of type LPWSTR

Any ideas?

Thanks

ConfusedBacon
  • 85
  • 2
  • 8

3 Answers3

9

LPWSTR is an alias for wchar_t*, ie a pointer to a non-const character.

A string literal is a const array of characters, in your case a const wchar_t[35]. It decays into a pointer to a const character, pointing at the 1st character in the literal.

You can't assign a pointer-to-const to a pointer-to-non-const. That would allow writing access to read-only memory.

Use LPCWSTR instead, which is an alias for const wchar_t*.

LPCWSTR test = L"C:\\Users\\user\\Pictures\\minion.png"; 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • while this is quite evident .. I am suspicious when confronted with MSDN examples that promote (well looks like) using LPWSTR .. for instance , this example : [Querying for Event Information](https://learn.microsoft.com/en-us/windows/win32/eventlog/querying-for-event-source-messages) – Mohammad Kanan Oct 29 '20 at 21:51
  • 1
    Most examples were written for C, or early C++ before C++11 started enforcing that non-const pointers could no longer point at string literals. – Remy Lebeau Oct 29 '20 at 21:55
  • hmmm , makes sense. Thanks! – Mohammad Kanan Oct 29 '20 at 21:57
  • This is finally starting to make sense for me, but how would I go about with the following usage given that the FormatMessage requires a LPWSTR: `FormatMessage(..., msg, 0, null); if(msg == null){msg = "L"Error: '" + to_wstring(GetLastError()) " + FormatMessage returned null.";` – Reahreic Jul 11 '23 at 20:00
  • @Reahreic That is not the correct way to check for failure. That code only makes sense if you use `FORMAT_MESSAGE_ALLOCATE_BUFFER`, in which case you need to pass a `wchar_t**` casted to `wchar_t*`. Third, you can't store a pointer to a temp string. Change `msg` into `wstring` and use `LPWSTR` for the allocation, eg: `wstring msg; LPWSTR buf = nullptr; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER, reinterpret_cast(&buf), 0, nullptr)) { msg = buf; LocalFree(buf); } else { msg = L"Error: '" + to_wstring(GetLastError()) + L"' FormatMessage failed."; }` – Remy Lebeau Jul 11 '23 at 21:23
4

The MSVC compiler is getting less and less permissive. On the whole that's a good thing.

L"C:\\Users\\user\\Pictures\\minion.png" is a literal of type const wchar_t[34] (the extra element is for the string terminator). That decays to a const wchar_t* pointer in certain circumstances.

LPWSTR is not a const pointer type so compilation will fail on a standard C++ compiler.

The solution is to use the const pointer type LPCWSTR.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0

Another way to resolve this compilation error is to set Conformance Mode to Default in the project Properties -> C/C++ -> Language. At least it worked in my VS2019 project.

Terry
  • 310
  • 3
  • 9