• 10
• 10
• 12
• 12
• 14

# L (again) new problem!

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

## Recommended Posts

Hello there, GO TO MY SECOND REPLY TO FIND A NEW PROBLEM I know, that if you're creating a windowsclass, and you name it:
// somewhere in int WINAPI WinMain(...)
wcex.lpszClassName	= "Class";


You need to place an L before it or embrace it with TEXT(), if your in unicode.
// somewhere in int WINAPI WinMain(...)
wcex.lpszClassName	= L"Class";


But what if you use a variable:
// some where in the declarations
const char g_szClass[] = "Class";

// somewhere in int WINAPI WinMain(...)
wcex.lpszClassName	= g_szClass;


I can't place an L before it in the declaration, because it's a char there. And I also can't place it in WinMain, because Lg_szClass is no existing variable. What is the best way to solve this? -Stenny [Edited by - stenny on July 20, 2006 6:42:22 AM]

##### Share on other sites
You need to include <tchar.h>

Then, you declare all your chars as TCHAR, put TEXT() or _T() around all of your string constants and you are away.

Good thing about this is it will resolve to the correct form whether UNICODE is on or not.

#include <tchar.h>const TCHAR *Name=_T("Hello");

HTH Paul

##### Share on other sites
@Dhm
Thanks, that worked:

// some where in the declarationsconst char g_szClass[] = "Class";// somewhere in int WINAPI WinMain(...)wcex.lpszClassName	= L" (g_szClass) ";

@EasilyConfused
That worked too, yours is even better. But what if I don't declare the char at the creation, like:

void AppError(BOOL Fatal, char *Text, ...){	TCHAR *CaptionText[12];	TCHAR *ErrorText[2048];	va_list valist;	// build the messagebox caption based on fatal flag //	if (Fatal == FALSE)	{		strcpy(CaptionText, "Error");	} else {		strcpy(CaptionText, "Fatal Error");	}	// build the variable text buffer //	va_start(valist, Text);	vsprintf(ErrorText, Text, valist);	va_end(valist);	// Display the messagebox //	MessageBox(NULL, ErrorText, CaptionText, MB_OK | MB_ICONERROR);	// Post a quit message if error was fatal	if (Fatal == TRUE)	{		PostQuitMessage(0);	}}

This is the complete function

##### Share on other sites
Quote:
 Original post by stenny@DhmThanks, that worked:// some where in the declarationsconst char g_szClass[] = "Class";// somewhere in int WINAPI WinMain(...)wcex.lpszClassName = L" (g_szClass) ";

Uh...

Now, it don't work. the content of g_szClass[] is not automagically copied into the brand new string (L"(g_szClass)"). This evaluate to a string which contains "(g_szClass)" in unicode.

Quote:
 Original post by stenny@EasilyConfusedThat worked too, yours is even better. But what if I don't declare the char at the creation, like:void AppError(BOOL Fatal, char *Text, ...){ TCHAR *CaptionText[12]; TCHAR *ErrorText[2048]; va_list valist; // build the messagebox caption based on fatal flag // if (Fatal == FALSE) { strcpy(CaptionText, "Error"); } else { strcpy(CaptionText, "Fatal Error"); } // build the variable text buffer // va_start(valist, Text); vsprintf(ErrorText, Text, valist); va_end(valist); // Display the messagebox // MessageBox(NULL, ErrorText, CaptionText, MB_OK | MB_ICONERROR); // Post a quit message if error was fatal if (Fatal == TRUE) { PostQuitMessage(0); }}This is the complete function

To work with TCHAR strings, you have to use TCHAR* functions, not the char* C functions. For example, strcpy() is now _tcscpy(). Your code becomes:
void AppError(BOOL Fatal, TCHAR *Text, ...){	// be aware that using such kind of code makes your program	// vulnerable to buffer overflow attacks. Moreover, it allocates	// a very big area on the stack (in UNICODE, 4120 bytes) 	TCHAR CaptionText[12]; // why did you declared an array of string?	TCHAR ErrorText[2048]; // same question	va_list valist;	// build the messagebox caption based on fatal flag //	if (Fatal == FALSE)	{		_tcscpy(CaptionText, "Error");	} else {		_tcscpy(CaptionText, "Fatal Error");	}	// build the variable text buffer //	va_start(valist, Text);	_vstprintf(ErrorText, Text, valist);	va_end(valist);	// Display the messagebox //	MessageBox(NULL, ErrorText, CaptionText, MB_OK | MB_ICONERROR);	// Post a quit message if error was fatal	if (Fatal == TRUE)	{		PostQuitMessage(0);	}}

You also have another alternative: go to your project properties, and select the proper characater set (multi-byte vs. unicode). This will undefine the UNICODE macro in your code, meaning that you'll get rid of these L, TEXT() and wide char string stuff. Of course, using TCHAR would still be a must, because it will allow you to do a simple recompile to build eitehr the unicode version of your program or the non-unicode version.

HTH,

##### Share on other sites
Sorry Stenny - perhaps I should have mentioned that you can't just then use TCHAR interchangably with char* like that. MSDN has a wealth of information about the compatible function equivalents.

##### Share on other sites
Quote:
 Original post by EasilyConfusedEmmanuel - sort your quote tags out [smile]. That really confused me for a minute.

Done [smile]

##### Share on other sites
@Emmanuel
Uh...

Quote:
 Now, it don't work. the content of g_szClass[] is not automagically copied into the brand new string (L"(g_szClass)"). This evaluate to a string which contains "(g_szClass)" in unicode.

It worked though.

Quote:
 To work with TCHAR strings, you have to use TCHAR* functions, not the char* C functions. For example, strcpy() is now _tcscpy(). Your code becomes:

Thanks. I know of the other solutions (changing to non-unicode), but that has indeed that disadvantage.

Quote:
 Sorry Stenny - perhaps I should have mentioned that you can't just then use TCHAR interchangably with char* like that. MSDN has a wealth of information about the compatible function equivalents.

Thanks, but the AppError needs those functions though. I normally just use char*, but if VS throws up the error (cannot convert from char* to lPCWSTR or something like it), I change it with TCHAR.

-Stenny

EDIT
the array of string? it was an array of chars first.
And if it uses that much memory...is there another way?!

##### Share on other sites
Quote:
Original post by stenny
@Emmanuel
Uh...

Quote:
 Now, it don't work. the content of g_szClass[] is not automagically copied into the brand new string (L"(g_szClass)"). This evaluate to a string which contains "(g_szClass)" in unicode.

It worked though.

It appeared to work, but it doesn't do what you expect it to do (this is the real definition of "working" [smile]). Your code seems to assume that wcex.lpszClassName will contain "Class" but it contains only "(g_szClass)". If later you want to compare the class name with "Class", the test will fail.

Edit:
Quote:
 Original post by stennyEDITthe array of string? it was an array of chars first.And if it uses that much memory...is there another way?!

Yes, using dynamic allocation (or better: if you are programming using C++, you can use a std::vector<> to ease the job).

Regards,

##### Share on other sites
ok. So we'll have to scrap that option. Wait...Can't I just create LPCWSTR's from scratch? Like:

const LPCWSTR g_szClass = "Classname";

- Stenny