win32 file to listbox

Nov 21, 2011 at 9:28am
All I am trying to do is put the contents of a text file in a WIN32 listbox. When I run the following code, I get lines of "||||" in the listbox. The console 'cout' function prints out the correct text from the file. What conversion is needed to get a readable listing? Is 'sendmessage' the only way to put text into a listbox?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
case IDM_FILEOPEN:					
	file_selected = openfilename() ;//get a file
	if (file_selected == true)// if a file has been selected open a list box and fillit
		{
			hlistBox = CreateWindow(
			_T("listbox"),
			NULL,
			WS_CHILD | WS_VISIBLE | WS_SYSMENU | WS_CAPTION | WS_VSCROLL,

			
			10,
			10,
			500,
			500,
			hWnd,
			hMenu,//IDC_LISTBOX,
			hInstance,
			NULL);
			// TEMP string for conversion from System::String to STD:string
			a = gcnew String (ofn.lpstrFile);
			int index = 0; /*what line number to pass*/
			StreamReader^ sr = gcnew StreamReader((a));
			while ((line = sr->ReadLine()) != nullptr)
				{
					line2 = marshal_as<std::string>(line);
					char *sz;
					cout << "line2 = " << line2 << endl;
					sz = new char[line2.length() + 1];
					strcpy(sz, line2.c_str());
					cout << "sz = " << sz << endl;
					SendMessage(hlistBox,LB_ADDSTRING,NULL,(LPARAM)sz);

					index++;

				}
			sr->Close();
Nov 21, 2011 at 11:20am
Try using Send MessageA or possibly change your last 'while' loop as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while ((line = sr->ReadLine()) != nullptr)
				{
					line2 = marshal_as<std::basic_string<TCHAR>>(line);
					TCHAR *sz;
					cout << "line2 = " << line2 << endl;
					sz = new TCHAR[line2.length() + 1];
					_tcscpy(sz, line2.c_str());
					cout << "sz = " << sz << endl;
					SendMessage(hlistBox,LB_ADDSTRING,NULL,(LPARAM)sz);

					index++;
                                        delete [] sz;

				}



Or, even better, do this:

1
2
3
4
5
6
7
8
while ((line = sr->ReadLine()) != nullptr)
				{
					line2 = marshal_as<std::basic_string<TCHAR>>(line);
					SendMessage(hlistBox,LB_ADDSTRING,NULL,(LPARAM)line2.c_str());

					index++;

				}
Last edited on Nov 21, 2011 at 11:24am
Nov 21, 2011 at 9:10pm
As, going by the pointers, you're using C++/CLI, you do have another way. Rather than mixing managed pointers and old-school WIN32, you could switch to WinForms, and use code like

list->Items->Add(line);

Or do you want to or need to use raw WIN32 ??
Last edited on Nov 21, 2011 at 9:11pm
Dec 5, 2011 at 6:43pm
if anyone is interested I found one way to get the desired output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while ((line = sr->ReadLine()) != nullptr)
	{	
		line_lenght = line->Length;
		char *lpBuffer = new char[256];
		for (int t =0;t<256;t++)//clear out the garbage
			lpBuffer[t] = (WCHAR)' ';
		if (line_lenght > 0)// must have some data
		{
			for (int t =0;t<line_lenght;t++)// replace a lpBuffer char with a line char, one char at a time
			lpBuffer[t] = line[t];
		}	
		SendMessage(hlistBox, LB_ADDSTRING, NULL, (LPARAM)lpBuffer);
		delete [] lpBuffer;
		index++;
Dec 5, 2011 at 8:13pm
A few questions:

1. I don't get the WCHAR cast? lpBuffer is a pointer to a char buffer, so why is it needed?

2. Why set all elems to a space rather than to '\0'?

3. Do you need to new and delete a 256 long buffer for every single line, rather than allocate it once and just clear it each time? (For such a small buffer I'd leave it on the stack).

4. Why not use strcpy()? Are you copying Unicode wchar_ts into a char buffer???


Dec 6, 2011 at 7:24pm
Is there some benefit to using a ListBox vs a multiline Edit? Just curious.
Dec 7, 2011 at 3:26pm
Texan40:

My original objective is to simply list the contents of a ascii text file in some kind of closable window. The window could be 'notepad ' if I can figure how to use it in my WIN32 app. The lines never exceed 100 characters, up to 900 lines (the lines are are machine instructions).
I have settled on WIN32 for the apps because WIN32 gives me the graphics I need. I have tried visual basic, opengl, java and several other envirements.

andywestkem:

You have good questions. WCHAR cast? In earlier attempts I kept getting conversion errors. I not sure how the code even works!. I found the lpBuffer code online somewhere. The lpBuffer code was used once to store a filename ,then send it to a listbox.
I added the following trying to get something to work.
1
2
3
4
5
6
7
for (int t =0;t<256;t++)//clear out the garbage
			lpBuffer[t] = (WCHAR)' ';
		if (line_lenght > 0)// must have some data
		{
			for (int t =0;t<line_lenght;t++)// replace a lpBuffer char with a line char, one char at a time
			lpBuffer[t] = line[t];
		}	

I have searched and searched for a way to send multiple lines to a WIN32 listbox.
If either of you have better code, please let me know. I don't understand all of the c++ stuff yet. There should "trial and error" before my ID.
Dec 7, 2011 at 5:39pm
if you are reading from a file it would be very easy to do a line-by-line read into a listbox. Something like:

1
2
3
4
5
6
7
8
9
std::string lineBuffer;
std::ifstream inputFile("test.txt");
if(inputFile.good())
{
  while(std::getline(inputFile,lineBuffer))
  {
    SendMessage(hlistBox, LB_ADDSTRING,0,(LPARAM)lineBuffer.c_str());
  }
}


if you want strict WIN32 then probably instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HFILE hInputFile = (HFILE)CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(hInputFile != INVALID_HANDLE_VALUE)
{
  char c;
  std::string line;
  while(ReadFile(hInputFile,&c,1,0,0))
  {
    if(c = '\n')
    {
      SendMessage(hlistBox, LB_ADDSTRING,0,(LPARAM)line.c_str());
      line.clear();
    } else {
      line += c;
    }
  }
}
Last edited on Dec 7, 2011 at 5:40pm
Dec 8, 2011 at 3:38pm
Texan:
The "std::string lineBuffer;" code works flawlessly. I added "inputFile.close()". I hope this is correct. Is there some reading material you can recommend on C++? You program for a living?

Thank you for helping.
Topic archived. No new replies allowed.