MessageBox producing different output than Cout C++ - 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;

Related

Buffer Allocation With GetModuleFileNameEx

I am currently trying to get the full filepath from my executable by providing a process ID, and this works "fine" in the since that its able to return some of the information needed, however for some reason it becomes corrupted and this can be seen when trying to return it as a plain string: C and if you iterate over each char and print each letter you get even more of a mess. Where is my current coding wrong when attempting allocate my buffer?
std::string User::getFullPath() {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId());
char buffer[MAX_PATH];
if (hProcess != NULL)
{
GetModuleFileNameEx(hProcess, NULL, (LPWSTR)buffer, MAX_PATH);
CloseHandle(hProcess);
}
for (char i : buffer) {
std::cout << i<<std::endl;
}
return buffer;
}
How do I properly allocate the memory in this case to prevent corruption
First off, the contents of your array are uninitialized if OpenProcess() fails. There is no need to use OpenProcess() on the calling process ID. Use GetCurrentProcess() instead, or simply use GetModuleFileName() instead.
That said, the real problem is not with memory allocation, but rather is that you are mixing ANSI and Unicode incorrectly. You are typecasting a char[] buffer to wchar_t*, which won't work.
You need to either:
use a wchar_t[] instead:
std::wstring User::getFullPath() {
wchar_t buffer[MAX_PATH] = {};
GetModuleFileNameW(NULL, buffer, MAX_PATH);
std::wcout << buffer << std::endl;
return buffer;
}
use GetModuleFileName(Ex)A() instead:
std::string User::getFullPath() {
char buffer[MAX_PATH] = {};
GetModuleFileNameA(NULL, buffer, MAX_PATH);
std::cout << buffer << std::endl;
return buffer;
}

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();

C++ fstream is writing hex instead of string?

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.

GetWindowText Can't Handle TradeMark Symbol

HWND ForeWindow = GetForegroundWindow();
wchar_t WindowTxt[1024] = { L'\0' };
GetWindowTextW(ForeWindow, WindowTxt, 1024);
wprintf(L"%s\n", WindowTxt);
std::wstring Str(WindowTxt);
std::wcout << L"Wnd: " << Str << L"\n";
Using the above code to get the window of skype which is "Skype™" i get the output:
"Skype?"
(the wcout line fails to execute)
1) Why is the wide character version of GetWindowText unable to handle this character
2) Why does std::wstring fail to parse the wchar_t array and then print it to the console
CMD consoles don't handle Unicode well. Send the output to a file and open it in and editor, and I suspect you'll get the actual character you expect.

How to pass std::string to CreateDirectory with Unicode set

I am having difficulty with the CreateDirectory function. In the following code I am getting a
"cannot convert argument 1 from 'const char *' to 'LPCWSTR'" compile error for the CreateDirectory call.
// make path to folder in program data
char szPath[MAX_PATH];
if ( ! SUCCEEDED( SHGetFolderPathA( NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath ) ) )
{
std::cout << "ERROR: Could not open server log - no common data folder " << std::endl;
exit(1);
}
std::string fname = szPath;
fname +="/Point";
CreateDirectory( fname.c_str(), NULL);
I am using Visual Studio 2015 and have "Character Set = Use Unicode Character Set".
In fileapi.h the following is defined:
#ifdef UNICODE
#define CreateDirectory CreateDirectoryW
#else
#define CreateDirectory CreateDirectoryA
#endif // !UNICODE
So I think the CreateDirectoryW function is being used
What do I need to do to get this to compile properly?
You need to use std::wstring instead of std::string in order to use wide character strings.
int main()
{
// make path to folder in program data
wchar_t szPath[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath)))
{
std::cout << "ERROR: Could not open server log - no common data folder " << std::endl;
exit(1);
}
std::wstring fname = szPath;
fname += L"/Point";
CreateDirectory(fname.c_str(), NULL);
}
If you do not want to use wide character strings you need to explicitly call the narrow character versions of the windows API functions such as CreateDirectoryA instead of CreateDirectory.
Use CreateDirectoryA.
That said you'd be better off changing to Unicode in your application, wide text.
The original code has some problems:
// make path to folder in program data
↑ This comment is misleading: the code is about finding the path, not creating it.
char szPath[MAX_PATH];
↑ This buffer is unnecessary, instead, for this code, you should just declare the later variable std::string fname here, with specified buffer size.
if ( ! SUCCEEDED( SHGetFolderPathA( NULL, CSIDL_COMMON_APPDATA, NULL, 0, szPath ) ) )
↑ !SUCCEEEDED is a misleading rewrite of idiomatic FAILED. And SHGetFolderPath is deprecated. Instead you should be using SHGetKnownFolderPath.
{
std::cout << "ERROR: Could not open server log - no common data folder " << std::endl;
exit(1);
}
↑ The console output makes this failure handling of little value in a GUI program. Anyway, instead of cout you should be using cerr or clog (they both map to the standard error stream by default). In the exit call you should either be using a standard value such as EXIT_FAILURE, or supply the HRESULT that you got (this is Windows convention, in particular for crashing programs), or for some function, the value that you get from GetLastError. Anyway exit is far too drastic. You should be either throwing an exception or returning an optional.
std::string fname = szPath;
fname +="/Point";
↑ Forward slashes are generally supported but still the Windows convention is backslash as item separator.
CreateDirectory( fname.c_str(), NULL);
↑ The only problem that it doesn't compile with UNICODE defined before including windows.h. Use CreateDirectoryA. Or better, switch to Unicode.