Well, let's examine what LPCSTR and LPTSTR actually are. I believe their definitions are in windef.h and look like this:
Code:
typedef const CHAR FAR *LPCSTR;
typedef TCHAR FAR *LPCTSTR;
OK, let's move further. FAR is a #define that's a relic from 16-bit Windows. In 32-bit Windows, i.e. everything since Win95, it's defined to nothing.
CHAR is just a typedef for char, nothing interesting. So LPCSTR is effectively a const char*.
TCHAR is more interesting. Its definition looks approximately like this:
Code:
#if defined(UNICODE)
typedef WCHAR TCHAR;
#else /* UNICODE */
typedef CHAR TCHAR
#endif /* UNICODE */
In other words, if the preprocessor symbol UNICODE is defined, TCHAR is the same as WCHAR, which is an unsigned short, but more importantly it's what Windows considers a Unicode character. In other words, a LPTSTR is a mutable Unicode string when UNICODE is defined.
When it's not defined, TCHAR is the same as CHAR, and LPTSTR is just a mutable C-style narrow string.
Now, before I show you the conversion, a short note: OpenFile is outdated. It's another of those Win16 relics. Nowadays you should use CreateFile. Don't be misled by the name: CreateFile doesn't necessarily create a file on disk. It can also open it, or open a special device, and a few other things. What it actually creates is an OS file handle.
Now, CreateFile takes an LPCTSTR as the filename parameter, and the problem just goes away: you can always pass a mutable string where an immutable one is expected.
But for the conversion, it works like this: if UNICODE is not defined, the T variant and the naked variant are the same. You can just assign. The other way round, i.e. going from the const to a mutable version, requires you to allocate a buffer and copy the string, but it's still straight-forward and can be accomplished e.g. with lstrcpyA or strcpy, or perhaps strcpy_s in VS.Net 2005.
If UNICODE is defined, however, the types differ, and a cast is not sufficient to convert. (In fact, a cast is a catastrophic idiocy that I've seen all too often.) You need to allocate a buffer for the string and call WideCharToMultiByte or a functionally equivalent function (wcstomb comes to mind) to convert the string. The other way round is accomplished with the opposite function, MultiByteToWideChar (or mbtowcs). Since you have to allocate a buffer anyway, constness is not an issue.
But the best way is still to avoid the issue of conversion as much as possible. Use the generic types for all strings. Wrap all string literals in the TEXT() macro (or the _T() macro from tchar.h). Use only generic functions: all WinAPI functions are generic, and the tchar.h header provides generic variants of nearly all CRT functions that deal with strings or characters.
Note that tchar.h switches on _UNICODE, not UNICODE like windows.h does.