getting garbage using SendMessage to populate a Listbox - c++

I'm trying to populate a Listbox using c++ on Visual Studio. I have an array of std:string and i want to use them. My solution doesn't seem to work:
std::string label = "something";
char *buffer;
buffer = _strdup((label).c_str());
I checked and the buffer variable contains the correct string, but then i call SendMessage
SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)buffer);
The ListBox gets populated, but instead of "something" i see some random japanese characters...

SendMessage is a macro and it may be defined to SendMessageW, which uses Unicode string.
You are using std::string and char, so try using SendMessageA, which uses ANSI strings, explicitly.

Related

Why OutputDebugString is empty

I create a Win32 app and I have a logIn form, but I can't get a Edit Window value. I did it like this, but get nothing. Where is my mistake?
#define passwordWindowId 2
HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), WS_VISIBLE | WS_CHILD, 10, 80, 150, 20, hWnd, (HMENU)passwordWindowId, NULL, NULL);
int len = GetWindowTextLength(GetDlgItem(passwordWindowHandle, passwordEditId));
LPWSTR passwordWindowValue;
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
OutputDebugString(passwordWindowValue);
But if I do OutputDebugString(L"test"); I see test in output tab.
Lots of errors in your code, some subtle and others fatal.
#define passwordWindowId 2
Some of the low control IDs are used by the dialog manager, and should not be overloaded with user-defined controls. A common convention is to start assigning numbers starting at 100 (see Why do dialog editors start assigning control IDs with 100?).
Another common convention is to use all uppercase names for preprocessor symbols.
HWND passwordWindowHandle = CreateWindow(TEXT("EDIT"), TEXT(""), ...
This is creating an empty edit control (see the second parameter of CreateWindow). This is not a bug in itself, but you cannot assume that the control contains any text.
Again, not a bug, but using the generic text mappings is generally not helpful. Use the Unicode versions of the APIs together with wide character strings and string literals: HWND passwordWindowHandle = CreateWindowW(L"EDIT", L"", ....
LPWSTR passwordWindowValue;
LPWSTR is a typedef for wchar_t*, so the above defines a pointer without initializing it. Not a bug in itself, but when you start using that pointer you run into undefined behavior. You need to allocate storage for the following call to GetWindowText, either by creating a local array of fixed size, if you know the maximum size ahead of time, or use a dynamically sized container (e.g. std::vector<wchar_t> buffer(len + 1);).
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
This is where things break: You are requesting an API call to write to unallocated memory, pointed to by an uninitialized pointer. As pointed out above, you need to allocate memory before calling GetWindowText. Besides, you are calling the generic text mapping, but passing explicit wide character string types. Use GetWindowTextW instead.
OutputDebugString(passwordWindowValue);
The argument is still an uninitialized pointer. Even if it weren't, the memory pointed to would be an empty string, since the control text is empty. Again, you are calling a generic text mapping, while passing an explicit wide character string. Use OutputDebugStringW instead.
Plus, you aren't checking for errors at all. All Windows API calls you are using can fail, and you need to check for failure. See the documentation on how to check for errors for each API call.
Updated!!
LPWSTR passwordWindowValue;
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
This should be
LPWSTR passwordWindowValue = new wchar_t[len + 1];
GetWindowText(passwordWindowHandle, passwordWindowValue, len + 1);
You are passing an uninitalised pointer to GetWindowText
And delete [] passwordWindowValue after you are done.

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";

Adding a string to a listbox results in weird characters

I have made a function that send strings to listbox using WIN32
char data[] = "abcd";
addToList(hWnd,data);
void addToList(HWND hWnd,char data[] ){
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX),LB_ADDSTRING,0,(LPARAM)data);
}
when I execute this it's send data to list box but the problem they appeared in weird characters, I have tried wchar_t also but the problem still issued
First of all, you should be checking your API calls for errors. You need to check the return values of all your calls to API functions.
That said, given the code in the question,
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX),LB_ADDSTRING,0,(LPARAM)data);
If that results in an item being added to the list box, then it means that GetDlgItem did indeed return a valid window handle, and data did indeed point to valid memory. In which case the only explanation for what you report is that the text encoded did not match.
So, we can assume that the SendMessage macro evaluates to SendMessageW. And since you are passing ANSI encoded text, that mismatch explains the symptoms. The function treats the text as UTF-16 encoded.
One obvious solution is to use SendMessageA instead. However, a better solution, in my view, would be to pass UTF-16 encoded data.
wchar_t data[] = L"abcd";
....
void addToList(HWND hWnd, const wchar_t *data)
{
SendMessage(GetDlgItem(hWnd,IDC_LISTBOX), LB_ADDSTRING, 0, (LPARAM)data);
}
Obviously your code would add in the error checking that I mentioned at the start.

CEdit and GetwindowText in MFC

I have added a simple Cedit control to my dialog and have an OnEnChangeEdit callback. I am trying to retrieve the text that is typed in the box, but can only get the first character of what is typed in that call to printf below:
void MFCDlg::OnEnChangeEdit() {
CString s;
m_platformSliceOverrideEditBox.GetWindowText(s);
_cprintf("%s", s.GetString());
}
If it helps I am using the Unicode character set for compilation.
_cprintf expects ansi strings. If you are using unicode then it will stop at the first character because the second byte will be a null.
use _tcprintf instead which will expect wide strings when you build as unicode.

How to view the value of a unicode CString in VC6?

I'm using Visual Studio 6 to debug a C++ application. The application is compiled for unicode string support. The CString type is used for manipulating strings. When I am using the debugger, the watch window will display the first character of the string, but will not display the full string. I tried using XDebug, but this tool does not handle unicode strings properly. As a work around, I can create a custom watch for each character of the string by indexing into the private array the CString maintains, but this is very tedious.
How can I view the full, unicode value of a CString in the VC6 debugger?
Go to tools->options->Debug, and check the "Display unicode string" check-box. That would probably fix the problem. Two other options:
In the watch window, if you have a Unicode string variable named szText, add it to the watch as szText,su. This will tell VS to interpret it as a Unicode string (See Symbols for Watch Variables for more of this sort).
Worst comes to worst, you can have a global ANSI string buffer, and a global function that will get a Unicode CString and store its content as ANSI, in that global variable. Then, when need call that function with the string whose content you'd like to see in the watch window, and watch the ANSI buffer.
But the "Display unicode string" thing is probably the problem...