how to read the contents of a textbox into a std::string

hello every one
i am making a program what requires that the user types in some text in a textbox.
the problem is, how do i get that text from the textbox into the std::string (or a other kind of string)?
i don't know how to do that in Win32, which i am using.

i had already tried to use the GetDlgItemText() function (and similar functions), but i don't know how to use that function, because i am not that good at C++. i don't know where and how to use that function.


i am using Microsoft Visual Studio 2010,
i am not using a windows form.
You call the function whenever you need it. I cannot say anything else in regards to this point without knowing more about the program.

1
2
3
4
5
int bufSize = 1024;
LPTSTR szText = new TCHAR[bufSize];
GetDlgItemText(hWndOfDialog, ID_OF_TEXTBOX, szText, bufSize);
std::string myString = szText;
delete[] szText;


That should do it. Where to place it? I don't know. In the processing of some WM_COMMAND message maybe? You call this whenever you need it.
it has errors with the line of "std::string myString = szText"even if i make the variables to a global variable(see code)
here is a bit of my code


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
LRESULT CALLBACK winProcCB(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	
	switch (uMsg)
	{

	
	case WM_CREATE:
		CreateWindow(TEXT("edit"), TEXT (""),
			WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
			0,0,200,100,
			hWnd, (HMENU) 2, NULL, NULL);
		break;


		
	
	case WM_DESTROY:
		PostQuitMessage(WM_QUIT);
		break;

	case WM_COMMAND:
 
         // read the textbox?
		break;

	
	
	default:
		return DefWindowProc(hWnd,uMsg,wParam,lParam);
	}
	return 0;
}

Don't make me guess. What errors did you receive? Show the code exactly as you tried it along with the errors you got.
Make sure that the file has a .cpp extension and not .c. There are two compilers a C and C++ and they treat code differently. Also ensure you include the relevant header files. It also helps if you were more specific about exactly what the error message is and where it occurs.
1
2
std::string input;
GetWindowText (handle, reinterpret_cast <char*> ((char *) input.c_str ()), 100);
Last edited on
Without running WriteGreatCode's code, I will venture say it is incorrect. I imagine that the reinterpret_cast<> there is not enough because c_str() is const while the parameter is not. Of course const_cast<> could be used but this is totally unnecessary.

Finally, the input variable have not reserved 100 bytes of RAM to receive the text (unless std::string by default allocates 100 bytes and I was completely unaware of this fact).

Oh, and finally (now it is true, hehe), we should remember that we should work with code that could be ANSI or UNICODE, so we should define tstring:

1
2
3
4
5
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif 


And then use tstring.
I forgot to convert c_str ()'s return value into a char * type and not a const char*. That is the only error in that code. And yes, webJose, it works (besides my mistake that I fixed). I wouldn't of posted it if it didn't.

Working Example:
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <windows.h>
#include <string>
#include <iostream>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Code::Blocks Template Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
		case WM_CREATE:
			CreateWindow ("edit", 0, WS_CHILD | WS_VISIBLE | WS_BORDER, 5, 5, 130, 20, hwnd, (HMENU) 1000, GetModuleHandle (NULL), NULL);
			CreateWindow ("button", "Click me", WS_CHILD | WS_VISIBLE, 5, 30, 130, 20, hwnd, (HMENU) 1001, GetModuleHandle (NULL), NULL);
			break;
		case WM_COMMAND:
			switch (LOWORD (wParam))
			{
				case 1001:
					{
						std::string input;
						GetWindowText (GetDlgItem (hwnd, 1000), reinterpret_cast <char*> ((char *) input.c_str ()), 100);
						MessageBox (hwnd, input.c_str (), "", MB_OK);
					}
					break;
			}
			break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Last edited on
Erm, actually that code is wrong because c_str doesn't have to return a pointer to it's own memory (so if you hack around it with casts [EVIL]) you could also either crash the system (writing to read-only memory) or overwrite random data. As it stands, what you are doing is very dangerous...just get it into a const char* like normal then construct an std::string from it.
Still here without testing code, hehe. Do you happen to know why this works? Why input.c_str() throws a suitable buffer when none has been requested? Is the mere declaration enough to get 100 characters worth of used RAM?
Well, it doesn't have a buffer, you are just writing over random memory. However, since you almost immediately output it, it probably hasn't changed yet (and you haven't seen any problems that might have occurred).

Also, I doubt the OS just hands you exactly the amount of memory you need. So if you say "new char", you might get a chunk of memory, so when you new more stuff you'll just take memory out of the chunk instead of going to the OS every time.
I see. So this is a bomb waiting to explode, as I imagined in the first place. Thanks for dropping by, firedraco to clear things up. I was losing my mind here thinking that the STL string class was allocating memory right away for no need, hehe. kirenemook12, stick to my code then.
when i try this:
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
38
39
40
LRESULT CALLBACK  wndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	
	switch (uMsg)
	{

	
	case WM_CREATE:
		CreateWindow(TEXT("edit"), TEXT (""),
			WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
			0,0,200,100,
			hWnd, (HMENU) 2, NULL, NULL);
		break;


		
	
	case WM_DESTROY:
		PostQuitMessage(WM_QUIT);
		break;

		
	case WM_KEYDOWN:
		bufSize = 1024;
		 szText = new TCHAR[bufSize];
		GetDlgItemText(hWnd,2, szText, bufSize);
		 myString = szText;
		delete[] szText;

		break;

	
	
	default:
		return DefWindowProc(hWnd,uMsg,wParam,lParam);
	}
	return 0;
}



I get the following errors from my IDE:

1>------ Build started: Project: omniProg, Configuration: Debug Win32 ------
1>Build started 24-3-2011 17:11:33.
1>InitializeBuildStatus:
1>  Touching "Debug\omniProg.unsuccessfulbuild".
1>ClCompile:
1>  All outputs are up-to-date.
1>  omniProg.cpp

1>c:\users\erik\documents\visual studio 2010\projects\omniprog\omniprog\omniprog.cpp(262): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:\users\erik\documents\visual studio 2010\projects\omniprog\omniprog\omniprog.cpp(416): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'LPTSTR' [/b](or there is no acceptable conversion)
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(707): could be 'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(std::basic_string<_Elem,_Traits,_Ax> &&)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(762): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const std::basic_string<_Elem,_Traits,_Ax> &)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(767): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(const _Elem *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xstring(772): or       'std::basic_string<_Elem,_Traits,_Ax> &std::basic_string<_Elem,_Traits,_Ax>::operator =(_Elem)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>,
1>              _Ax=std::allocator<char>
1>          ]
1>          while trying to match the argument list '(std::string, LPTSTR)'
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.31
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

it might has anything to do with the variable types?

Since Elem=char, I suppose this is an ANSI build and not a Unicode build. But it should work either way, unless you are trying to use std::string in a Unicode build. If this is a Unicode build then you must use std::wstring. Are you using the tstring definition I posted?

1
2
3
4
5
6
7
8
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif

//And this is how you must declare the myString string.
tstring myString;
thank you all very much, it worked. reading a textbox is very important to GUI programming
Topic archived. No new replies allowed.