117

First of all, what is it exactly? I guess it is a pointer (LPC means long pointer constant), but what does "W" mean? Is it a specific pointer to a string or a pointer to a specific string? For example I want to close a Window named "TestWindow".

HWND g_hTest;
LPCWSTR a;
*a = ("TestWindow");
g_hTest = FindWindowEx(NULL, NULL, NULL, a);
DestroyWindow(g_hTest);

The code is illegal and it doesn't work since const char[6] cannot be converted to CONST WCHAR. I don't get it at all. I want to get a clear understanding of all these LPCWSTR, LPCSTR, LPSTR. I tried to find something , however I got confused even more. At msdn site FindWindowEx is declared as

HWND FindWindowEx(      
    HWND hwndParent,
    HWND hwndChildAfter,
    LPCTSTR lpszClass,
    LPCTSTR lpszWindow
);

So the last parameter is LPCSTR, and the compiler demands on LPCWSTR. Please help.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
lhj7362
  • 2,173
  • 4
  • 19
  • 17
  • 84
    Welcome to Microsoft Hungarian notation. – Thomas Matthews Feb 09 '10 at 17:33
  • 2
    it actually makes for far more readable documentation, pity everything else about it sux. – Matt Joiner Feb 09 '10 at 17:39
  • 1
    @Thomas: This is **not** what Microsoft (or Simonyi for that matter) initially tagged *Hungarian Notation*. It's more or less the result of an accident, when the documentation group decided to exercise some "readability" improvements. They weren't developers and consequently the changes weren't graceful. Background information is available at [Hugarian notation - it's my turn now :)](http://blogs.msdn.com/b/oldnewthing/archive/2004/06/22/162629.aspx) – IInspectable Oct 21 '14 at 18:48
  • @IInspectable: Broken link – Nicolas Raoul Mar 04 '16 at 07:33
  • @NicolasRaoul: Yes, unfortunately. It doesn't seem to have been moved to the blog's new home, and may be gone for good. – IInspectable Mar 04 '16 at 11:51
  • 2
    @IInspectable: Working link is https://blogs.msdn.microsoft.com/larryosterman/2004/06/22/hugarian-notation-its-my-turn-now/ – Julius Bullinger Aug 08 '16 at 13:07
  • @JuliusBullinger: Thank you. I was specifically referring to [this comment](https://blogs.msdn.microsoft.com/larryosterman/2004/06/22/hugarian-notation-its-my-turn-now/#comment-7981) on the blog entry. – IInspectable Aug 08 '16 at 14:36

3 Answers3

166

LPCWSTR stands for "Long Pointer to Constant Wide String". The W stands for Wide and means that the string is stored in a 2 byte character vs. the normal char. Common for any C/C++ code that has to deal with non-ASCII only strings.

To get a normal C literal string to assign to a LPCWSTR, you need to prefix it with L:

LPCWSTR a = L"TestWindow";
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 8
    Just to expand - the 'LONG' part is a hangover from 16bit windows and can be ignored (excpet you need it in the name) – Martin Beckett Feb 09 '10 at 16:51
  • 17
    "hangover from 16bit Windows" -- That's for sure! – John Dibling Feb 09 '10 at 17:05
  • 1
    So the Hungarian Notation lies. Microsoft must go through all their API and source code and correct all of the names. This is why I don't use Hungarian Notation! – Thomas Matthews Feb 09 '10 at 17:34
  • 4
    Nope, it's correct. It was and is a 32 bits pointer. There are no "short" 16 bits pointers anymore, so you could complain if you manage to find a `SPCWSTR`. – MSalters Feb 10 '10 at 10:44
  • More like - the "L" is simply unnecessary - it should be just PCWSTR, as a pointer is always (and has been always) 32 bits. The question is, why did they put L on in the first place? My guess is just convention that "everything must have a size designator". Which is what I don't like about Hungarian - in well-written code, if you NEED to know the type of a variable when reading an algorithm, it should be in the name (ie WindowPtr, windowHandle, shortCharHandle, WideCharConstDontEverEdit, etc). – Jim Witte Mar 17 '12 at 18:03
  • 60
    My God. L??? The letter L? Not even a function, L()? Just plain L? Who the heck came up with that?? – john k Jan 06 '13 at 23:02
  • 15
    @user396483 It's common in many languages to add prefixes and suffixes to constants to change how they are represented, without changing their meaning to a human. For example, `36UL` in C# is the same as `(ulong)36` (ulong being an unsigned 64-bit integer). `@` can be used in the same language as a prefix for strings, changing how they are parsed slightly. – Zenexer Jul 19 '13 at 13:58
  • 2
    At least VS friends should warn of the need for the leading `L`, not even a quick fix suggestion... – Jaime Hablutzel Jan 19 '14 at 19:17
  • @Thomas: Risking a guess I'd say, that you haven't understood (Apps) Hungarian Notation. Do yourself a favor and download a copy of the Word 1.1a source code, to see Hungarian Notation used by developers in the know. – IInspectable Oct 21 '14 at 13:21
  • 3
    @IInspectable: I have already studied Hungarian Notation. One of my big peeves is that nobody updates the notation when the variable's type changes. I prefer to leave the variable's type out of the name. You should download and read all the articles against Hungarian Notation. Also, remember, Microsoft does not set the standards; they only spread many copies. And from the articles on Hungarian Notation, MS doesn't follow it completely. – Thomas Matthews Oct 21 '14 at 14:37
  • 2
    @Thomas: The ultimate goal of Hungarian Notation is [Making Wrong Code Look Wrong](http://www.joelonsoftware.com/articles/Wrong.html). Apps Hungarian Notation has **nothing** to do with encoding the concrete data type. It helps to disambiguate between a `RECT` storing screen or client coordinates, an `int` representing logical or device pixels, a buffer size argument being in characters (`cch`) or bytes (`cb`), or a `char*` pointing to an ASCII or UTF-8-encoded string. If you can find an article with a single valid argument against **Apps** HN, bring it on. I won't hold my breath, though. – IInspectable Oct 21 '14 at 18:03
  • 4
    The L is ridiculous, What if you need to convert a variable to a LPCWSTR?!! Why does Microsoft have such insane viewpoints?! – Mehdi Ijadnazar Sep 05 '16 at 16:20
16

LPCWSTR is equivalent to const wchar_t *. It's a pointer to a wide character string that won't be modified by the function call.

You can assign a string literal to LPCWSTR by prepending the literal with the L prefix, eg:

LPCWSTR myStr = L"Hello World";

LPCTSTR and any other T types, take a string type depending on the Unicode settings for your project. If UNICODE is defined for your project, the use of T types is the same as the wide (Unicode) character forms, otherwise the narrow (Ansi) character forms. The appropriate API functions will also be called this way, eg:

FindWindowEx is defined as FindWindowExA or FindWindowExW depending on this definition.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Matt Joiner
  • 112,946
  • 110
  • 377
  • 526
  • How do I check if I'm using correct unicode settings on a fresh install of VS and on a fresh console app project? My Farsi characters are showing as '?' question marks even though the problem is not from the command prompt, other apps print Farsi characters just fine. – Shayan May 06 '22 at 08:54
7

It's a long pointer to a constant, wide string (i.e. a string of wide characters).

Since it's a wide string, you want to make your constant look like: L"TestWindow".

I wouldn't create the intermediate a either, I'd just pass L"TestWindow" for the parameter:

ghTest = FindWindowEx(NULL, NULL, NULL, L"TestWindow");

If you want to be pedantically correct, an "LPCTSTR" is a "text" string -- a wide string in a Unicode build and a narrow string in an ANSI build, so you should use the appropriate macro:

ghTest = FindWindow(NULL, NULL, NULL, _T("TestWindow"));

Few people care about producing code that can compile for both Unicode and ANSI character sets though, and if you don't then getting it to really work correctly can be quite a bit of extra work for little gain. In this particular case, there's not much extra work, but if you're manipulating strings, there's a whole set of string manipulation macros that resolve to the correct functions.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 1
    you don't need to be pedantically correct, use _T() if you're using constants like _T(MAIN_WINDOW) otherwise LMAIN_WINDOW will fail. – Rodolfo Nov 13 '12 at 22:56
  • @JerryCoffin "*If you want to be pedantically correct ... you should use the appropriate macro*" - which would be `TEXT()` in this case, not `_T()`. `UNICODE`, `TCHAR`, `LPCTSTR`, `TEXT()`, etc come from the Win32 API, whereas `_UNICODE`, `_TCHAR`, `_T()`, etc come from the C runtime library instead. Even though they are *mostly* interchangable, you should use the appropriate types/macros for the API you are using. – Remy Lebeau Jul 06 '23 at 00:43
  • @Rodolfo you can't use `_T()` (or `TEXT()`) with declared constants, only with string/character literals directly. – Remy Lebeau Jul 06 '23 at 00:45
  • @RemyLebeau: If I ever decide to write a Win32 program that doesn't use the standard library, I might try to keep that in mind. Doesn't seem very likely to happen though... – Jerry Coffin Jul 06 '23 at 02:21