Variable type with MoveFile() in VC++ - c++

So I am trying to move a file that the user specifies by using cin and MoveFile(). But the thing is MoveFile() parameters take LPCTSTR variables but cin doesnt take those variable types can anyone help me with a conversion from a char myChars[] table to a LPCTSTR variable? Any help is appreciated.

LPCTSTR is a typedef. It's actually another type: It's a long pointer to a const TCHAR string. Or, in other words, it's a const TCHAR*.
A TCHAR is also a typedef, but it's either a char or a wide character, depending on whether your project is using Unicode or ASCII. They usually default to Unicode.
You can use MoveFileA to force ASCII. Then, a LPCTSTR is literally a const char*.

Related

Qt5.9.9+Vs2017 encountered a character set problem [duplicate]

I'm learning to write and use DLLs and this is my first attempt at exporting a function from my dll. It works, but this line is what gave me trouble and what I've been able to find regarding the TEXT cast for UNICODE and ANSI I think I need some guidance. As far as I can find this question has not been asked elsewhere on the site so I apologize if anyone finds what I couldn't.
HINSTANCE hInstLibrary = LoadLibrary("MyDLL.dll");
My initial usage, from a short tutorial on explicit linking gives E0167 and C2664 errors regarding LPCWSTR type
HINSTANCE hInstLibrary = LoadLibrary(TEXT("MyDLL.dll"));
Casting the string to TEXT solves the problem, though I'm not sure why and would like to know
HINSTANCE hInstLibrary = LoadLibraryA("MyDLL.dll");
The line I decided to use in the working example. LoadLibraryA() expands LoadLibrary to accept ANSI rather than Wide, which may be the root of my misunderstanding. Why is this necessary when most examples I find show LoadLibrary("NameOfDLL.dll")?
Why does the string not satisfy the standard LoadLibrary() call?
LoadLibrary() is a preprocessor macro. It maps to either LoadLibraryW() or LoadLibraryA() depending on whether UNICODE is defined or not, respectively. LoadLibraryW() takes a const wchar_t* string as input, while LoadLibraryA() takes a const char * string instead.
The string literal "MyDLL.dll" is a const char[10], which decays into a const char *. If UNICODE is defined, LoadLibrary("MyDLL.dll") will fail to compile, as you cannot pass a const char * where a const wchar_t * is expected.
TEXT() is also a preprocessor macro. If UNICODE is defined, it appends an L prefix to the specified literal making the literal use wchar_t, otherwise no prefix is added and the literal uses char instead.
Thus, if UNICODE is defined, then LoadLibrary(TEXT("MyDLL.dll")) is compiled as LoadLibraryW(L"MyDLL.dll"), otherwise it is compiled as LoadLibraryA("MyDLL.dll") instead.
A majority of Win32 APIs that deal with textual data have similar A and W versions, and corresponding UNICODE-aware preprocessor macros. So, when using character/string literals with these APIs, you should always use the TEXT() macro. Otherwise, just use the A and W APIs directly as needed, depending on the type of textual data you are working with.

Exporting functions from DLLs, LoadLibrary() needs the string cast with TEXT to compile without error

I'm learning to write and use DLLs and this is my first attempt at exporting a function from my dll. It works, but this line is what gave me trouble and what I've been able to find regarding the TEXT cast for UNICODE and ANSI I think I need some guidance. As far as I can find this question has not been asked elsewhere on the site so I apologize if anyone finds what I couldn't.
HINSTANCE hInstLibrary = LoadLibrary("MyDLL.dll");
My initial usage, from a short tutorial on explicit linking gives E0167 and C2664 errors regarding LPCWSTR type
HINSTANCE hInstLibrary = LoadLibrary(TEXT("MyDLL.dll"));
Casting the string to TEXT solves the problem, though I'm not sure why and would like to know
HINSTANCE hInstLibrary = LoadLibraryA("MyDLL.dll");
The line I decided to use in the working example. LoadLibraryA() expands LoadLibrary to accept ANSI rather than Wide, which may be the root of my misunderstanding. Why is this necessary when most examples I find show LoadLibrary("NameOfDLL.dll")?
Why does the string not satisfy the standard LoadLibrary() call?
LoadLibrary() is a preprocessor macro. It maps to either LoadLibraryW() or LoadLibraryA() depending on whether UNICODE is defined or not, respectively. LoadLibraryW() takes a const wchar_t* string as input, while LoadLibraryA() takes a const char * string instead.
The string literal "MyDLL.dll" is a const char[10], which decays into a const char *. If UNICODE is defined, LoadLibrary("MyDLL.dll") will fail to compile, as you cannot pass a const char * where a const wchar_t * is expected.
TEXT() is also a preprocessor macro. If UNICODE is defined, it appends an L prefix to the specified literal making the literal use wchar_t, otherwise no prefix is added and the literal uses char instead.
Thus, if UNICODE is defined, then LoadLibrary(TEXT("MyDLL.dll")) is compiled as LoadLibraryW(L"MyDLL.dll"), otherwise it is compiled as LoadLibraryA("MyDLL.dll") instead.
A majority of Win32 APIs that deal with textual data have similar A and W versions, and corresponding UNICODE-aware preprocessor macros. So, when using character/string literals with these APIs, you should always use the TEXT() macro. Otherwise, just use the A and W APIs directly as needed, depending on the type of textual data you are working with.

Are MFC CString and LPTSTR interchangeable?

I am trying to use a DLL with an ANSI C compiler. One of the DLL functions takes a void pointer. In some sample Windows code that was provided with the DLL, the struct that gets passed to the function is defined as having three CString entities. I have told the author of the DLL that they should not be passing MFC classes through their DLL functions. They have told me just to replace the CString declarations in the struct with char arrays and it should be fine. I'm 99% sure that's wrong, but since I don't have VC++ and don't have any experience with MFC, and since I've seen some posts saying LPTSTR can be used in place of CString (What is `CString`?), I'm starting to wonder if I'm wrong.
Can someone please confirm for me that CString and LPTSTR are not interchangeable as arguments to a function? If you can provide the source for the definition of the CString class, that would be helpful so I can send it to the DLL's author and explain that the memory footprint of a char array is not the same as a CString class, and that you can't pass a pointer to a struct that was defined with char arrays and then treat it as a bunch of CString objects.
CString is an alias of the CStringT class template. Objects of this class are really better not to pass to the DLL. The character type of the string class can be TCHAR (for both ANSI and Unicode character strings - see explanation below). The definition of CString (and CStringT) can most likely be found in the atlstr.h header file.
LPTSTR is a regular pointer to a sequence of characters. The data type (TCHAR*) depends on the settings of the development environment: if the "Use Unicode Character set" option is selected, the TCHAR data type will be wchar_t (and LPTSTR will be wchar_t*, respectively). If the "Use Multi-byte character set" is selected, the TCHAR will be defined as char (and LPTSTR will be char*).
So the question about interchangeability between CString and LPTSTR is not so simple. It also depends on how the DLL is written. If the DLL was designed with the same environment settings as the main program, then CString and LPTSTR can really be interchangeable.
Also, remember that CStirng is a class with many methods, while LPTSTR is just a pointer.

Is MFC CString a wide char string

I'm working on a win32 project with CStrings (console application), and I noticed something odd when I want to pass to a function (like strtok_s for example) a LPSTR pointer from a CString with the method GetBuffer(), this last one instead of giving me a LPSTR, it gave me a LPWSTR (a pointer to a wide string)... CString is supposed to store 8 bit chars isn't it ?
I'm obliged in some cases to use CStringA for example to be able for example to use the method Find() because with a CString my input string must be a wide one. But in other another project (windowed program), I don't have this problem, i'm suspecting the headers (when I use afxstr.h "Find" works with a normal string, but not with afxcoll.h...)
Usually I work with std::string that's why I'm lost.
CString is a typdef, declared as (afxstr.h):
typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;
// Or, when using the MFC DLL
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;
Depending on what TCHAR is, a CString stores either an ANSI (MBCS) or Unicode string. There are also explicit instantiations of the CStringT template: CStringW and CStringA.
Either type has a conversion constructor, taking a constant pointer to the respective other character encoding. In other words: You can construct a CStringW from an ANSI (MBCS) string, as well as a CStringA from a UTF-16LE-encoded Unicode string.
If you need to be explicit about the character encoding, use either CStringW or CStringA.
Full documentation for CString is available at CStringT Class.

creating a LPCTSTR pointer to a string in VS2010

I have to feed a LPCTSTR in to CreateProcess.
The short question is how do I convert a std::string into a LPCTSTR?
( LPCTSTR lpApplicationName = (LPCTSTR)FilePath.c_str(); does not work, CreateProcess simply ignores it, I know the path etc. I'm using is right because it works perfectly if I put in LPCTSTR lpApplicationName = L"a//test//path//and//file";).
The long question (why I need to do this) is: This LPCTSTR has to contain the path to, and name of, a file I wish to run.
The process is:
To get the path into the right format for CreateProcess I am having
to perform character replace (replacing single \ with double \ ) on
the output from GetModuleFileName. This output starts off as a
WCHAR buffer and I then convert into a std::string.
I then also need to concatenate this string with the final file name
which could be in any variable type (I define it in the program).
The finished string goes into the CreateProcess LPCTSTR.
I have tried using other sorts of string, but so far I haven't found any that the concatenate and character replace will work on.
Every solution I have seen does not work in Visual Studio 2010, which is what I'm using. All advice gratefully received.
LPCTSTR is a pointer to a const TCHAR*, not a const char*. Depending on your UNICODE and _UNICODE settings you will need either a std::wstring or a std::string. If you are stuck with std::string then you need to convert the char* returned by c_str() to a wchar_t* string (or not depending on UNICODE).
To make life a little easier on yourself I recommend:
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif