how to convert or cast CString to LPWSTR?

17,404

Solution 1

If I recall correctly, CString is typedef'd to either CStringA or CStringW, depending on whether you're building Unicode or not.

LPWSTR is a "Long Pointer to a Wide STRing" -- aka: wchar_t*

If you want to pass a CString to a function that takes LPWSTR, you can do:

some_function(LPWSTR str);

// if building in unicode:
some_function(selectedFileName);

// if building in ansi:
some_function(CA2W(selectedFileName));

// The better way, especially if you're building in both string types:
some_function(CT2W(selectedFileName));

HOWEVER LPWSTR is non-const access to a string. Are you using a function that tries to modify the string? If so, you want to use an actual buffer, not a CString.

Also, when you "check" temp -- what do you mean? did you try cout << temp? Because that won't work (it will display just the first character):

char uses one byte per character. wchar_t uses two bytes per character. For plain english, when you convert it to wide strings, it uses the same bytes as the original string, but each character gets padded with a zero. Since the NULL terminator is also a zero, if you use a poor debugger or cout (which is uses ANSI text), you will only see the first character.

If you want to print a wide string to standard out, use wcout.

Solution 2

In short: You cannot. If you need a non-const pointer to the underlying character buffer of a CString object you need to call GetBuffer.

If you need a const pointer you can simply use static_cast<LPCWSTR>(selectedFilename).

Solution 3

I know this is a decently old question, but I had this same question and none of the previous answers worked for me.

This, however, did work for my unicode build:

LPWSTR temp = (LPWSTR)(LPCWSTR)selectedFileName;
Share:
17,404
Luis Gabriel Fabres
Author by

Luis Gabriel Fabres

Ingeniero Informático de amplio prontuario... cuando no estoy programando, voy en bicicleta, o estoy bebiendo cerveza..

Updated on June 07, 2022

Comments

  • Luis Gabriel Fabres
    Luis Gabriel Fabres almost 2 years

    I tried to use this code:

    USES_CONVERSION;
    LPWSTR temp = A2W(selectedFileName);
    

    but when I check the temp variable, just get the first character

    thanks in advance

  • Luis Gabriel Fabres
    Luis Gabriel Fabres over 10 years
    Hi, thnank for u reply..I meant that in the function that is called from the web page, I get only the first character of the string (in this case the selected file) that's ,the letter 'C' which is the drive from which I am getting the name of the archive. apparently to convert CString to LPWSTR lost the rest of the string
  • IInspectable
    IInspectable over 10 years
    @Luis I doubt that anything got lost. It's just that you don't understand what how a UNICODE string is encoded in Windows. Make sure to read The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!). When done you will understand the why the different Format Specifiers are required for strings. You should use su.
  • Zac Howland
    Zac Howland over 10 years
    The cast only works if the program is built with the UNICODE flag, which maps TCHAR to wchar_t. If that flag is not turned on, it is a char, so doing a static cast will not give you what you want. Since CString has an overload for operator LPCTSTR(), there is no need to use static_cast - it will do the conversion implicitly.
  • IInspectable
    IInspectable over 10 years
    @Zac You are totally awesomely clever. Thanks for pointing out the obvious. And failing to be correct as well... CStringT does not have an operator LPCTSTR() overload. And its base class CSimpleStringT has operator PCXSTR defined. Whether or not a static_cast is required is a matter of compiler warning level and build tool sets. Feel free to omit it.
  • Zac Howland
    Zac Howland over 10 years
    In your effort to pick a fight, you completely missed the point. LPCTSTR = "long pointer to a constant t-string". PCXSTR = "pointer to a const x-string" where the x is filled in based on the template parameter declared with the CSimpleString<>. That is, if UNICODE is not defined, CString is basically a CSimpleString<char>, so trying to use static_cast<LPCWSTR> will not work, which is what you left out, and which is what I was pointing out.
  • IInspectable
    IInspectable over 10 years
    @Zac In all your awesomeness, why don't you provide your own answer then? I mean, give me a chance to downvote yours without a reason. It's only fair, no?
  • Zac Howland
    Zac Howland over 10 years
    I down-voted yours because it is not complete. I went on to describe how you can fix it. You seem to take things personally which makes it difficult to see that (unlike you), I wasn't attacking you, but noting what you needed to add to fix it. Since Tim has already posted an answer that is complete, there is no need for me to re-post what is already written and correct. But feel free to down-vote his post if you feel yours is better.
  • IInspectable
    IInspectable over 10 years
    @Zac I'm not taking this personal. It's just very obvious that you downvoted this answer as an act of revenge. If an answer is incomplete then it may not get my vote. With Visual Studio 2013 removing MBCS support for MFC altogether your point may not even hold. As a general guideline, downvotes should be used on answers that are complete and utter bogus.
  • MrHIDEn
    MrHIDEn almost 10 years
    UNICODE: CString cstring = "some"; LPWSTR lpwstr = cstring .GetBuffer(cstring .GetLength());
  • MrHIDEn
    MrHIDEn almost 10 years
    MULTICHAR: CString cstring = "some"; LPWSTR lpwstr = CT2W(cstring);