C++ fstream is writing hex instead of string? - c++

I'm trying to download a file using URLDownloadToFile() which is working so far, however I'm having trouble with the callback function and writing the callback output wszStatusText to a file.
Here is the function that's giving the problem:
HRESULT DownloadStatus::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR wszStatusText)
{
fstream myfile;
myfile.open("file.txt", ios::app);
// this prints hex
myfile << " StatusText: " << wszStatusText;
myfile.close();
// this prints the string properly
MessageBox(NULL, wszStatusText, L"test", MB_OK);
return S_OK;
}
The thing is that MessageBox() is showing the data properly...
UPDATE
After getting an exception error (using wfstream) I found out that the reason why it was giving me that because the first value of wszStatusText was NULL.

You are passing a wide character C-string into a narrow character stream. There is no good automatic conversion for that, so you just get a pointer address.
Use a std::wfstream instead.

Related

MFC Extract CString between tags

I'm trying to code a function to retrieve the value between two tags or characters using CStrings, so far I haven't been able to do so.
CODE REMOVED
I'm pretty sure StartIndex and EndIndex have the right values, however I'm stuck at the last step, where I'm supposed to extract the substring from between the tags.
EDIT:// Got it working, thanks to Igor Tandetnik. If anyone knows why SubStr only prints correctly with wcout if I explicitly cast it with (LPCWSTR) it would be greatly appreciated. I'm leaving the working code below in case someone else needs this or wants to improve it.
CString ExtractString(CString strSource, CString strStart, CString strEnd)
{
CString SubStr = L"";
int iEndIndex, iStartIndex = strSource.Find(strStart);
iStartIndex += strStart.GetLength();
iEndIndex = strSource.Find(strEnd, iStartIndex);
if (iStartIndex == -1 || iEndIndex == -1)
{
wcout << L"TAG not found!" << endl;
return SubStr;
}
SubStr = strSource.Mid(iStartIndex, (iEndIndex - iStartIndex));
SubStr.Trim();
return SubStr;
}
If you pass std::wstring to wcout, it works fine because those guys know each other. wcout will pick the right << operator for std::wstring
But C++ Standard Library and MFC are separate. wcout doesn't know what to do with CString, so it treats CString object as const void*, it uses operator<<(const void*) to print an address.
Next step, CString returns (const wchar_t*) buffer. But wcout had already decided on const void*, so wcout prints the address of that string buffer returned by CString.
(const wchar_t*) cast will instruct wcout to use the right << operator. You can also use CString::GetString() to let wcout know that wide characters are being sent.
wcout << LPCWSTR(SubStr);
//or
wcout << SubStr.GetString();

'SystemParametersInfo' function returns incorrect value when get the desktop wallpaper

I'm using the function SystemParametersInfo to get the desktop wallpaper and it's assumed that when adding the action SPI_GETDESKWALLPAPER to the function returns a string.
LPWSTR bgPath;
if(!SystemParametersInfo(SPI_GETDESKWALLPAPER, 0, bgPath, SPIF_UPDATEINIFILE)){
qDebug() << *bgPath;
return;
}
qDebug()<< "an error occurred";
The problem is that the function returns a numeric value (ex: 50121) instead of a string.
Is there any problem in my code?
You not allocating any memory for bgPath for SystemParametersInfo() to fill in.
Per the SPI_GETDESKTOPWALLPAPER documentation:
The pvParam parameter must point to a buffer to receive the null-terminated path string. Set the uiParam parameter to the size, in characters, of the pvParam buffer. The returned string will not exceed MAX_PATH characters.
Even if you were allocating a buffer, you are checking the return value of SystemParametersInfo() for failure instead of success. And you are dereferencing your string pointer, so at best you would output only the first character, not the whole string.
Use this instead:
WCHAR bgPath[MAX_PATH];
if (SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, bgPath, 0))
{
qDebug() << bgPath;
return;
}
qDebug() << "an error occurred";

VBA/Excel, and C++ DLL, specifically problems with strings

I am working on a project for serial communications between Excel and an Arduino. The following is what I have in VBA for the reading of data from the Arduino which is where my problem lies.
Private Declare Function readFromSerialPort Lib "C:PathToDll.dll"(ByRef Buffer As String) As String
And in a looping function within my VBA I have the following which sets a cell value to a string which is my buffer.
BigData.Range("Buf").Value = "B "
Another cell called dataWindow takes in Buf as an argument so it updates when this is called.
=readFromSerialPort(Buf)
And here is the C++ code on the other end in the DLL.
DLL_EXPORT BSTR WINAPI readFromSerialPort(LPBSTR bufferTemp) {
char errorMsg[] = "read failed";
char mbstring[MAX_STRING_SIZE];
BSTR wcstring = *bufferTemp;
int sLen = wcstombs(mbstring,wcstring,MAX_STRING_SIZE);
char charString[MAX_STRING_SIZE];
DWORD dwBytesRead = 0;
if (hSerial == INVALID_HANDLE_VALUE) {
ErrorExit("ReadFile (port not open)");
int wLen2 = mbstowcs(*bufferTemp,errorMsg,strlen(errorMsg));
return *bufferTemp;
}
if(!ReadFile(hSerial, charString, sLen, &dwBytesRead, NULL)) {
ErrorExit("ReadFile");
int wLen2 = mbstowcs(*bufferTemp,errorMsg,strlen(errorMsg));
return *bufferTemp;
}
int wLen2 = mbstowcs(*bufferTemp,charString,sLen);
return *bufferTemp;
}
The issue is that this works when called from a cell but not when I change it to declaring a string in VBA and calling the read from there.
GSerg has solved this issue. I had not understood that VBA automatically converts when passing as String, so that in the DLL I am not dealing with BSTRs but with ASCII char* or LPSTRs. Also that due to a bug in excel, calling functions from within a cell does not do this conversion.

MessageBox producing different output than Cout C++

I am trying to load the name of an image using its VM address by calling GetModuleFileName() which seems to return the value correctly into a TCHAR[] array. I am able to display the data correctly using MessageBox() but cout << seems to display some funky hexadecimal number.
TCHAR buf[MAX_PATH];
HMODULE hProc = LoadLibrary(TEXT("kernel32.dll"));
GetModuleFileName(hProc, buf, MAX_PATH);
cout << buf; //Produces the odd number
MessageBox(NULL, buf, NULL, MB_OK); //Produces correct filepath
FreeLibrary(hProc);
Am I supposed to set a flag for cout so it knows to print it correctly? Thank you!
Probably you need to use wcout, because your TCHAR might be unicodish. Or convert it.
Maybe you will have better luck with
std::wcout << buf;

COM : retrieve good CLSID

I have a little problem with the CLSID.
I have a (hooked) function which has in param a REFCLSID.
So I want to print this param.
I did:
LPOLESTR pOleStr;
StringFromCLSID(rclsid,&pOleStr); //rclsid is a REFCLSID type.
ofstream myfile;
myfile.open("C:\\output.txt",ios::app);
myfile << pOleStr << std::endl;
myfile.close();
But in "output.txt", I just have a 8 character string,
but I should have a string like : 111111-2222-3333-4444-000000000000.
So if anyone has an idea...
Thanks.
Just a guess, I think that LPOLESTR is widechar, you'd have to convert it to ASCII using
CHAR szCLSID[60];
WideCharToMultiByte(CP_ACP, 0, pOleStr, -1, szCLSID, 60, NULL, NULL);
Also don't forget to CoTaskMemFree(pOleStr) afterwards :)