120

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.

7
  • 87
    Welcome to Microsoft Hungarian notation. Commented Feb 9, 2010 at 17:33
  • 2
    it actually makes for far more readable documentation, pity everything else about it sux. Commented Feb 9, 2010 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 :) Commented Oct 21, 2014 at 18:48
  • @IInspectable: Broken link Commented Mar 4, 2016 at 7:33
  • 2
    @IInspectable: Working link is blogs.msdn.microsoft.com/larryosterman/2004/06/22/… Commented Aug 8, 2016 at 13:07

3 Answers 3

178

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"; 
Sign up to request clarification or add additional context in comments.

13 Comments

Just to expand - the 'LONG' part is a hangover from 16bit windows and can be ignored (excpet you need it in the name)
"hangover from 16bit Windows" -- That's for sure!
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.
My God. L??? The letter L? Not even a function, L()? Just plain L? Who the heck came up with that??
@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.
|
19

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.

1 Comment

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.
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.

4 Comments

you don't need to be pedantically correct, use _T() if you're using constants like _T(MAIN_WINDOW) otherwise LMAIN_WINDOW will fail.
@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.
@Rodolfo you can't use _T() (or TEXT()) with declared constants, only with string/character literals directly.
@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...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.