xboxscene.org forums

Author Topic: Wchar (unicode) To Standard Lpcstr  (Read 55 times)

clonexb

  • Archived User
  • Jr. Member
  • *
  • Posts: 63
Wchar (unicode) To Standard Lpcstr
« on: June 22, 2004, 01:10:00 AM »

Basically I have a problem, I need to convert a WCHAR (UNICODE) to a standard LPCSTR.

e.g.

Basically when I compile my XBOX code everything is UNICODE.

char strFind[] = "D:\\*";
WIN32_FIND_DATA wfd;
HANDLE hFind;

// Start the find and check for failure.
hFind = FindFirstFile( strFind, &wfd );

if( INVALID_HANDLE_VALUE != hFind )
{
// Display each file and ask for the next.
do
{
hFile = CreateFile( (LPCSTR) wfd.cFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY | FILE_FLAG_BACKUP_SEMANTICS, NULL );
dwSector = XGetFilePhysicalSortKey (hFile);


notice the first parameter is wfd.cFileName and is actually a WCHAR (UNICODE) and CreateFile expects an LPCSTR

Do you know how I can convert the wfd.cFileName to an LPCSTR ?

Thanks.
Logged

KaMbiOkIkA

  • Archived User
  • Newbie
  • *
  • Posts: 24
Wchar (unicode) To Standard Lpcstr
« Reply #1 on: June 22, 2004, 02:15:00 AM »

Hi,

Test that, it should work :

char cTemp[MAX_PATH];

sprintf(cTemp,"%S",wfd.cFileName);

hFile = CreateFile( (LPCSTR) cTemp,......


Bye
Logged

clonexb

  • Archived User
  • Jr. Member
  • *
  • Posts: 63
Wchar (unicode) To Standard Lpcstr
« Reply #2 on: June 22, 2004, 04:30:00 AM »

Thanks for trying but that didnt work :(
Logged

KaMbiOkIkA

  • Archived User
  • Newbie
  • *
  • Posts: 24
Wchar (unicode) To Standard Lpcstr
« Reply #3 on: June 22, 2004, 05:24:00 AM »

Hi,

Sorry, but i was at job so i should make mistake in the code so i will post you the exact solution after job.

Bye
Logged

clonexb

  • Archived User
  • Jr. Member
  • *
  • Posts: 63
Wchar (unicode) To Standard Lpcstr
« Reply #4 on: June 22, 2004, 06:00:00 AM »

ok thanks.
Logged

d0wnlab

  • Archived User
  • Sr. Member
  • *
  • Posts: 326
Wchar (unicode) To Standard Lpcstr
« Reply #5 on: June 22, 2004, 07:14:00 AM »

For VC I think the trick is to use the macro _T.

so use _T("this text")

iirc that was the solution I found for my winCE device, so it very well might not work for you.

Logged

clonexb

  • Archived User
  • Jr. Member
  • *
  • Posts: 63
Wchar (unicode) To Standard Lpcstr
« Reply #6 on: June 22, 2004, 07:23:00 AM »

ok, ill try thanks.
Logged

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Wchar (unicode) To Standard Lpcstr
« Reply #7 on: June 22, 2004, 08:18:00 AM »

Please note, he was using a CAPITAL "S" in the format specifier, which has special meaning in M$ C Runtimes... it means "Wide Character String"

The _T() macro is used to specify either a single byte or wide character, depending on your compiler setting... there are a whole slew of "t" macros to encapsulate the various functions associated with string functions:

Example:

strlen(const char *)/wcslen(const wchar *) -> _tcslen( LPCTSTR )

Wide characters are a major PITA, but understanding the conversion helps out. I use "StdString" object, which simulate CString using the STL "string" objects. As there are specific CStdStringW and CStdStringA types, and you can simply use assignment to convert, it's the easiest way in my code. The only thing there is to remember when using as a format (printf, or CStdString::Format) param, to use the .c_str() to force it to return a pointer to the character buffer)

You can grab "StdString.h" from my MXM source code to make your life easier.

Logged

clonexb

  • Archived User
  • Jr. Member
  • *
  • Posts: 63
Wchar (unicode) To Standard Lpcstr
« Reply #8 on: June 22, 2004, 12:13:00 PM »

thanks, that was very helpful :)
Logged

xxxfubar187xxx

  • Archived User
  • Newbie
  • *
  • Posts: 11
Wchar (unicode) To Standard Lpcstr
« Reply #9 on: June 22, 2004, 01:12:00 PM »

I'm not exactly sure which API's are supported but I use these when programming Windows CE devices:

MultibyteToWideChar -> CHAR (1 byte) to WCHAR (2 byte)

WidecharToMultibyte  -> WCHAR (2 byte) to CHAR (1 byte)


BUT>>>

LPCTSTR is type defined as a TCHAR and CreateFile takes a TCHAR as a parameter so that all looks good.

It looks to me like UNICODE isn't defined.

Try:
#define UNICODE

Also using L in front of a string will always be multibyte string.  Using TEXT or _T depends on whether UNICODE is defined or not.

Ex. If unicode IS NOT defined

L"String" = Wide character string
TEXT"String" = Multibyte character string

MSDN is a programmers best friend:
http://msdn.MS.com

This is from the winnt.h header file:

//
// Neutral ANSI/UNICODE types and macros
//
#ifdef  UNICODE                     // r_winnt

#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TBYTE, *PTBYTE;
typedef wchar_t _TCHAR;
typedef wchar_t _TSCHAR;
typedef wchar_t _TUCHAR;
typedef wchar_t _TXCHAR;
typedef wint_t _TINT;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */

typedef LPWSTR LPTCH, PTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR PCTSTR, LPCTSTR;
typedef LPWSTR LP;
#define __TEXT(quote) L##quote      // r_winnt

#else   /* UNICODE */               // r_winnt

#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TBYTE , *PTBYTE ;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */

typedef LPSTR LPTCH, PTCH;
typedef LPSTR PTSTR, LPTSTR;
typedef LPCSTR PCTSTR, LPCTSTR;
#define __TEXT(quote) quote         // r_winnt

#endif /* UNICODE */                // r_winnt


SAMPLE CODE:

//
//Calling this way gives the number of bytes needed to store the converted string
//likewise for WidecharToMultibyte
INT nBytes = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pSingleByteString, -1, NULL, NULL );

//
//Allocate space to store the wide character string
PWCHAR pWideString = (PWSTR)malloc( sizeof(WCHAR)*( nBytes + 1 )  );

//
//Use memset here or NULL terminate the string after conversion
memset( pWideString, 0, nBytes + 1 );

//
//Convert the single byte string to wide character
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pSingleByteString, strlen(pSingleByteString), pWideString, nBytes + 1 );


Hope that helps.....

This post has been edited by xxxfubar187xxx: Jun 22 2004, 08:26 PM
Logged

KaMbiOkIkA

  • Archived User
  • Newbie
  • *
  • Posts: 24
Wchar (unicode) To Standard Lpcstr
« Reply #10 on: June 22, 2004, 01:15:00 PM »

Hi,

Finally i'm at home so i test this :

char cTemp[MAX_PATH];

sprintf(cTemp,"%S",wfd.cFileName);

and it works perfectly for me so...

Bye
Logged

xxxfubar187xxx

  • Archived User
  • Newbie
  • *
  • Posts: 11
Wchar (unicode) To Standard Lpcstr
« Reply #11 on: June 22, 2004, 01:28:00 PM »

I'll save you some time IGNORE KaMbiOkIkA's last post.
Logged

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Wchar (unicode) To Standard Lpcstr
« Reply #12 on: June 22, 2004, 03:02:00 PM »

QUOTE (xxxfubar187xxx @ Jun 22 2004, 05:28 PM)
I'll save you some time IGNORE KaMbiOkIkA's last post.

Why? His code will convert a wide char to 8-bit characters.

The capital "S" is the key there. Examine M$ help documentation on printf format specifiers.
Logged

xxxfubar187xxx

  • Archived User
  • Newbie
  • *
  • Posts: 11
Wchar (unicode) To Standard Lpcstr
« Reply #13 on: June 22, 2004, 03:52:00 PM »

Yes thank you for pointing out the obvious.

MSDN:
The types C and S, and the behavior of c and s with printf functions, are MS extensions and are not ANSI compatible.

The way I described above is how we do it at MS.

Logged

BenJeremy

  • Archived User
  • Hero Member
  • *
  • Posts: 5645
Wchar (unicode) To Standard Lpcstr
« Reply #14 on: June 22, 2004, 04:01:00 PM »

QUOTE (xxxfubar187xxx @ Jun 22 2004, 07:52 PM)
Yes thank you for pointing out the obvious.

MSDN:
The types C and S, and the behavior of c and s with printf functions, are MS extensions and are not ANSI compatible.

The way I described above is how we do it at MS.

Well, it just seems there's bit of snippiness going on here... my point was that there are a number of ways to do the conversion, and KaMbiOkIkA's method should work fine, too. ;)

As for the way things are done at M$, well, I've seen quite a bit of that code, particularly CE code (having spent quite a bit of time developing automotive telematics systems), and I'd be wary about bragging about it  :lol:  ....but, I'm sure it's far better now than it was in the Moonraker/Thunderball days.  :o

Logged