c++stringwinapiwchar-tlpcwstr

Have a PCWSTR and need it to be a WCHAR[]


I am re-writing a C++ method from some code I downloaded. The method originally took a PCWSTR as a parameter and then prompted the user to enter a file name. I modified the method to take two parameters (both PCWSTR) and not to prompt the user. I am already generating the list of files somewhere else. I am attempting to call my new (modified) method with both parameters from my method that iterates the list of files.

The original method prompted the user for input using a StringCBGetsW command. Like this...

HRESULT     tst=S_OK;         //these are at the top of the method
WCHAR       fname[85] = {0};  //these are at the top of the method
tst = StringCbGetsW(fname,sizeof(fname));

The wchar fname gets passed to another iteration method further down. When I look at that method, it says it's a LPCWSTR type; I'm assuming it can take the WCHAR instead.

But what it can't do is take the PCWSTR that the method got handed. My ultimate goal is to try not prompt the user for the file name and to take instead the filename that was iterated earlier in another method.

tl;dr. I have a PCWSTR and it needs to get converted to a WCHAR. I don't know what a WCHAR [] is or how to do anything with it. Including to try to do a printf to see what it is.

PS...I know there are easier ways to move and copy around files, there is a reason I'm attempting to make this work using a program.


Solution

  • First, let's try to make some clarity on some Windows specific types.

    WCHAR is a typedef for wchar_t.
    On Windows with Microsoft Visual C++, it's a 16-bit character type (that can be used for Unicode UTF-16 strings).

    PCWSTR and LPCWSTR are two different names for the same thing: they are basically typedefs for const wchar_t*.

    The initial L in LPCWSTR is some legacy prefix that, read with the following P, stands for "long pointer". I've never programmed Windows in the 16-bit era (I started with Windows 95 and Win32), but my understanding is that in 16-bit Windows there were something like near pointers and far, or long pointers. Now we have just one type of pointers, so the L prefix can be omitted.

    The P stands for "pointer".
    The C stands for "constant".
    The W stands for WCHAR/wchar_t, and last but not least, the STR part stands for "string".

    So, decoding this kind of "Hungarian Notation", PCWSTR means const wchar_t*.
    Basically, it's a pointer to a read-only NUL-terminated wchar_t Unicode UTF-16 string.

    Is this information enough for you to solve your problem?

    If you have a wchar_t string buffer, and a function that expects a PCWSTR, you can just pass the name of the buffer (corresponding the the address of its first character) to the function:

    WCHAR buffer[100];
    DoSomething(buffer, ...);  // DoSomething(PCWSTR ....)
    

    Sometimes - typically for output string parameters - you may also want to specify the size (i.e. "capacity") of the destination string buffer.
    If this size is expressed using a count in characters (in this case, in wchar_ts), the the usual Win32 Hungarian Notation is cch ("count of characters"); else, if you want the size expressed in bytes, then the usual prefix is cb ("count of bytes").
    So, if you have a function like StringCchCopy(), then from the Cch part you know the size is expressed in characters (wchar_ts).

    Note that you can use _countof() to get the size of a buffer in wchar_ts.
    e.g. in the above code snippet, _countof(buffer) == 100, since buffer is made by 100 wchar_ts; instead, sizeof(buffer) == 200, since each wchar_t is 2 bytes == 16 bits in size, so the total buffer size in bytes is 100 [wchar_t] * 2 [bytes/wchar_t] = 200 [bytes].