Converting QString to LPCWSTR qt c++ - c++

Currently I am attempting to convert a QString to a LPCWSTR that will be used in URLDownloadToFile(). The following is a simple version of my current code:
QString url = "http://whatever_file...";
HRESULT hRez = URLDownloadToFile(NULL, (LPCWSTR)url.toLocal8Bit().constData(), TEXT("C:\\etc..."), 0, NULL);
The conversion was found working, in the post I found it in, with conversion of QString to LPCWSTR. I am rather new in the field of programming and I simply added a letter to that solution as URLDownloadToFile require it. It return no error however the download fail.
What am I missing here?

To get LPCWSTR from QString you can use QString::constData method, because QChar is 2 byte Unicode symbol, exactly as WCHAR (if wchar_t is 2 byte on target machine).
And I aware you from the using of "TEXT" macro in one line with "LPCWSTR". You should use "L" instead.
"TEXT" is created for using in pair with the "LPCTSTR" macro. You can read this about them.

Related

how to convert char* to LPCTSTR in c++(MFC)

I have to make MFC application that accesses .txt files.
The following code is part of the template file given:
fopen(dlg.GetPathName());
However when I tried to run given template file, I got errors indicating that char* can not be converted to LPCTSTR.
I did some research online, and the program runs fine after correcting like this:
USES_CONVERSION;
const char* cstr;
cstr = T2A((LPCTSTR)dlg.GetPathName());
~
fp = fopen(cstr, "r");
I'm mentioning this because my compiler(VS 2017 community) may use unicode as default. And I think this is key to solving the aforementioned problem:
I have a problem printing result on the window edit control.
m_Result.SetWindowTextW((LPCTSTR)Result);
Result contains the message to be displayed in edit control and its type is char*. Whenever I run the program the result it is displayed either in blank box □ or Chinese. I tried converting Result using A2T and CA2T and but none of these worked.
The first error can be fixed by using Microsoft's _wfopen() function (or the TCHAR equivalent, _tfopen(), to match the TCHAR nature of GetPathName() instead of fopen(). That way, you don't need to convert the input string to char* at all:
fp = _wfopen(dlg.GetPathName(), L"r");
fp = _tfopen(dlg.GetPathName(), _T("r"));
In the second error, if Result is char* (or something that is implicitly convertible to char*) and LPCTSTR maps to const wchar_t* (because UNICODE is defined) then you can use CA2CT just fine:
m_Result.SetWindowTextW(CA2CT(Result));
However, since SetWindowTextW() expects only wchar_t* and never TCHAR*, use CA2CW instead:
m_Result.SetWindowTextW(CA2CW(Result));
Alternatively, if possible, you should change Result to use wchar_t instead of char in the first place, then you don't need a conversion anymore:
m_Result.SetWindowTextW(Result);

Convert wide CString to char*

There are lots of times this question has been asked and as many answers - none of which work for me and, it seems, many others. The question is about wide CStrings and 8bit chars under MFC. We all want an answer that will work in ALL cases, not a specific instance.
void Dosomething(CString csFileName)
{
char cLocFileNamestr[1024];
char cIntFileNamestr[1024];
// Convert from whatever version of CString is supplied
// to an 8 bit char string
cIntFileNamestr = ConvertCStochar(csFileName);
sprintf_s(cLocFileNamestr, "%s_%s", cIntFileNamestr, "pling.txt" );
m_KFile = fopen(LocFileNamestr, "wt");
}
This is an addition to existing code (by somebody else) for debugging.
I don't want to change the function signature, it is used in many places.
I cannot change the signature of sprintf_s, it is a library function.
You are leaving out a lot of details, or ignoring them. If you are building with UNICODE defined (which it seems you are), then the easiest way to convert to MBCS is like this:
CStringA strAIntFileNameStr = csFileName.GetString(); // uses default code page
CStringA is the 8-bit/MBCS version of CString.
However, it will fill with some garbage characters if the unicode string you are translating from contains characters that are not in the default code page.
Instead of using fopen(), you could use _wfopen() which will open a file with a unicode filename. To create your file name, you would use swprintf_s().
an answer that will work in ALL cases, not a specific instance...
There is no such thing.
It's easy to convert "ABCD..." from wchar_t* to char*, but it doesn't work that way with non-Latin languages.
Stick to CString and wchar_t when your project is unicode.
If you need to upload data to webpage or something, then use CW2A and CA2W for utf-8 and utf-16 conversion.
CStringW unicode = L"Россия";
MessageBoxW(0,unicode,L"Russian",0);//should be okay
CStringA utf8 = CW2A(unicode, CP_UTF8);
::MessageBoxA(0,utf8,"format error",0);//WinApi doesn't get UTF-8
char buf[1024];
strcpy(buf, utf8);
::MessageBoxA(0,buf,"format error",0);//same problem
//send this buf to webpage or other utf-8 systems
//this should be compatible with notepad etc.
//text will appear correctly
ofstream f(L"c:\\stuff\\okay.txt");
f.write(buf, strlen(buf));
//convert utf8 back to utf16
unicode = CA2W(buf, CP_UTF8);
::MessageBoxW(0,unicode,L"okay",0);

Unable to convert the CStringW to CStringA

I am working on one project where I have stucked on one problem of converting CStringW to CStringA for multibyte string like Japanese Language.
I am loading the string from string resources using LoadString() Method.
I have tried following code but it does not seem to work.
CStringW csTest;
csTest.LoadString(JAPANESE_STRING);
CStringA Msg = CStringA(csTest); // Msg has been returned blank string
And
std::string Msg = CW2A(csTest);// Msg has been returned blank string
I have also tried
wcstombs() too.
Can anyone tell me how I can convert CStringW to CString?
Thanks in advance.
CStringW stores Unicode UTF-16 strings.
What encoding do you expect for your CStringA?
Do you want UTF-8?
In this case, you can do:
// strUtf16 is a CStringW.
// Convert from UTF-16 to UTF-8
CStringA strUtf8 = CW2A(strUtf16, CP_UTF8);
Talking about CStringA without specifying an encoding doesn't make sense.
The second parameter of CW2A is a what is passed to WideCharToMultiByte() Win32 API as CodePage (note that CW2A is essentially a convenient safe C++ RAII wrapper around this API). If you follow this API documentation, you can find several "code page" values (i.e. encodings).

LPCWSTR Error - C++

I'm trying to draw text to a window. Some enough, two things I'm wondering. Why can the tutorial I'm using not put an L"String Here" and I have to?
I'm confused about that, anyway back to the main point, I;m trying to draw text and I'm getting an error.
If you have UNICODE defined in your project (which you should be default) then you can either use
wstring s = L"Hello, World!";
or the ANSI API for TextOut
TextOutA(hdc, 10, 10, s.c_str(), s.size());
See the following question:
What does LPCWSTR stand for and how should it be handled with?
Basically, you're trying to convert a regular character string to a wide character string implicitly and it won't allow you to do that. From the top answer:
To get a normal C literal string to assign to a LPCWSTR, you need to prefix it with L
LPCWSTR a = L"TestWindow";

How do I store value to string with RegOpenKeyEx?

I need to grab the path from the registry. The following code works except for the last part where I'm storing the path to the string. Running the debugger in Visual Studio 2008 the char array has the path, but every other character is a zero. This results in the string only being assigned the first letter. I've tried changing char res[1024] to char *res = new char[1024] and this just makes it store the first letter in the char array instead of the string. The rest of the program needs the path as a string datatype so it can't stay as a char array. What am I missing here?
unsigned long type=REG_SZ, size=1024;
string path;
char res[1024];
HKEY key;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Classes\\dsn\\shell\\open\\command"), NULL, KEY_READ, &key)==ERROR_SUCCESS){
RegQueryValueEx(key,
NULL,// YOUR value
NULL,
&type,
(LPBYTE)res,
&size);
RegCloseKey(key);
path = string(res);
}
You're getting back a Unicode string, but assigning it to a char-based string.
You could switch path's class to being a 'tstring' or 'wstring', or use RegQueryValueExA (A for ASCII).
You are compiling in Unicode. Go to Project Settings>Configuration Properties>General and change "Character Set" to "Not Set", and rebuild your project.
RegOpenKey is actually a macro defined in the WINAPI headers. If Unicode is enabled, it resolves to RegOpenKeyW, if not then it resolves to RegOpenKeyA. If you want to continue to compile under unicode, then you can just call RetgOpenKeyA directly instead of using the macro.
Otherwise, you'll need to deal with Unicode strings which, if needed, we can help you with also.
For C++, you may prefer to access the Registry using the ATL helper class CRegKey. The method for storing string values is QueryStringValue. There are other (somewhat) typesafe methods for retrieving and setting different registry value types.
It's not the best C++ interface (eg. no std::string support) but a little smoother than native Win32.