Jump to content
  • Advertisement
Sign in to follow this  
FuzzeWuzze

LPCTSTR Undeclared Identifier

This topic is 3810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So, i am going through the Programming Role Playing games book and almost immediately ran into some problems. For the sake of saving space i cut out all the stuff that worked, what doesnt work is the WNDCLASSEX creation..in his call he uses WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0L, 0L, hInstance, NULL, NULL, NULL, NULL, "GameClass", NULL }; Any time i attempt to compile this, or ANY function which takes in a LPCTSTR it will fail with undeclared identifier. If i declare it first with like LPCTSTR className = "Game Class"; and then call the function it works perfectly. My question is, why? What is the difference? Obviously what hes doing works, or at least did work at some point or else it wouldn't be all throughout the book. Whats up?

Share this post


Link to post
Share on other sites
Advertisement
Its probably a unicode issue. In visual studio, when compiled with unicode, LPCTSTR defaults to a unicode character pointer(wchar_t *) and with unicode not set defaults to an ansi character pointer(char *). To fix this (in visual studio) either surround all text in _T() macros or turn off unicode support.

My guess is that whenever the book was written (perhaps in the days of visual c++ 6), unicode was either not supported or not enabled by default.

Share this post


Link to post
Share on other sites
Yeah, thats a common windows programming issue, they use their own defines for char*s, one thing I see is that its an LP*C*TSTR, I dont know what the "T" is for
but
LP = "long pointer", basically just your '*' on the char*

C = "constant"

T = "char_t?" EDIT: I looked it up, T = "null Terminated"

STR = "string"

so this is a "long pointer to a constant char_t", try making your char* const, or const casting. Personally if I ever see those errors I just C style cast them away because I am lazy and they pop up all the time

WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc, 0L, 0L, hInstance, NULL, NULL, NULL, NULL, (LPCTSTR)"GameClass", NULL };

so I would do that. Not the "best practice" but whatever, it works, and I know what its doing.

hmm, my WNDCLASSEX struct I am using takes a LPCSTR, not an LPCSTR so I cant check if type casting will help or not.

[Edited by - Lazerbeard on June 12, 2008 2:47:22 AM]

Share this post


Link to post
Share on other sites
I like to think of the T as meaning "template". Basically, if it's a TCHAR or TSTR it means that the underlying type depends on whether UNICODE is defined or not. When UNICODE is defined the these types use WCHAR as their underlying type, otherwise they use CHAR.

As a result, casting will cause serious errors in your program. In a great number of cases, casting is certainly NOT your friend. Saving casting for when you are absolutely sure that it is the right thing to do.

Share this post


Link to post
Share on other sites
I apologise, I looked it up in my Windows Programming book to make sure it was ok to just cast, it is most certainly not. I do remember having a similar problem with Message boxes, I believe to convert a string to a wchar_t you just put an L in front of the string, so it looks like

L"I am a wide character string"

Let me know if that works for you, I cant try it out on my own machine since I only have 2008 on here now due to a recent format, but if memory serves that will work.

EDIT: ahh heres the difference

#ifdef UNICODE
typedef LPCWSTR, LPCTSTR;
#else
typedef LPCSTR, LPCTSTR;
#endif

so apparently if you have UNICODE defined, which I hear is defined by default in Visual Studio 2005, LPCTSTR gets mapped to a LPCWSTR, and if not just an LPCSTR

so that means that T does mean "templated" like Colin said, so that a string can be in unicode or not depending on your define. For reference W is what actually makes something a Wide character string, or unicode.

So according to the book you should indeed just be able to tack that 'L' on there and it will work.

Share this post


Link to post
Share on other sites
Prepending L to your string literals will cause you the same grief as not since you are explicitly stating the underlying type (L"" means a wide-character string, "" means a narrow-character string). The best solution, in my opinion and experience, is to use either the _T or TEXT macro as mkuhlens suggested.

Also, in reference to the edit to your first post, T does not mean that the string is null terminated. Z means that. I dont believe there are any datatypes that include Z but if you see any example code marked up in Hungarian Notation, string variable names will often be marked up as lpszFoo meaning 'long pointer string zero-terminated'.

Share this post


Link to post
Share on other sites
Yeah, I forgot to unedit that post after I thought that sounded suspect, (I found that off another forum post) then I remembered I had a copy of Charles Petzold's book, and that if anywhere would have correct info on this it would, and T does sort of denote what you were saying about it being "templatized".

I can also see what you're saying about the TEXT macro, I assume it just tacks the L on there when UNICODE is defined and doesn't when UNICODE is not defined? I had seen that macro before, and I wasn't sure what exactly it did so I decided not to use it. I knew about Windows' use of UNICODE, but I didn't know they had it worked like that, this has been really interesting. I'm gonna go read the rest of the chapter on unicode stuff to make sure theres nothing else I'm missing...

Share this post


Link to post
Share on other sites
There's a rather lengthy entry in my journal about this Unicode/TCHAR nonsense, if you feel like reading it.

Share this post


Link to post
Share on other sites
Avoid the "T" versions of Windows APIs like the plague. There's three real possibilities, which unfortunately, T covers none of them:

a) You want to use ANSI strings. In which case, the Windows API usually has A versions of methods and some classes.

b) You want to use Unicode strings. In which case, the Windows API usually has W versions of methods and some classes.

c) You want both ANSI and Unicode strings. In which case, my solution usually is to wrap the function or class in a template function or class, and possibly defer down to another template class to specialize the two variations. I know C++ template specialization can be a bit of a tricky topic to get a grasp on, at first, but it can really make the code much more friendly when you have the case of needing both.

Again, avoid anything relating to TCHAR like the plague. It's one of the areas where I applaud Microsoft for effort to handle the two cases, but am surely unimpressed (actually downright discouraged and appalled) when it comes to how they implemented it. It seriously produces some rather brittle code, IMHO.

Share this post


Link to post
Share on other sites
I disagree with explicit use of the A versions and W versions of the functions. I do, however, agree that the T versions of the datatypes are no longer useful since every Windows OS that hasnt been end-of-life'd uses Unicode natively.

Unless you want your program to run on Windows 9x, stick with the W versions and if you're really concerned that someone might try to compile your program without UNICODE defined, just #define it before including windows.h. This way, you wont have to use the W versions of the functions and can safely use the L prefix to your literals since you've already made the commitment to be all Unicode.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!