Reading text into a string from edit style window

Hi everyone,

I am working on one of my first windows.h projects, and this really stumped me; I cannot seem to find a way to get the input the user has typed into a text box, and then store that in a variable.

A little background on what I want to do:

> User executes the program
> text file with required info is in the same directory, just need the name
> prompt for the name, and have an edit field for the file name
> user presses ok button when ready to proceed (I can get my program to respond to buttons, but Im stuck on the text input portion)
> when the user has pressed ok, the program reads the data from the edit box, stores it, closes the window, and opens a different window after preforming several actions.

Here is ALL of the code so far. (Sorry that I have to post all of it, im not sure exactly what is and isn't relevant with win32 GUI projects yet)

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
104
105
106
107
108
109
110
111
112
113
114
115
#include <windows.h>
#include <string>

std::string textfilename; // Variable to store the name of the file.

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

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

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 = GetSysColorBrush(COLOR_3DFACE);

    /* 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 */
           "Wii Game Organizer",       /* Title Text */
           WS_SYSMENU, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           400,                 /* The programs width */
           250,                 /* 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_CREATE:
            CreateWindow (TEXT("STATIC"), // User prompt
                         TEXT("Enter the name below of the file you want to open. Include the extension."),
                         WS_VISIBLE | WS_CHILD,
                         10,10,380,50,
                         hwnd, (HMENU) NULL,NULL,NULL
                         );
            CreateWindow (TEXT("edit"), ///This is the one I could really use help reading, it is where the filename is written, and needs to be read from
                          TEXT(""),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          50,100,300,20,
                          hwnd,(HMENU) 2, NULL,NULL);
            CreateWindow (TEXT ("BUTTON"), // This is the ok button, which signifies the user is finished typing the file name
                          TEXT("Ok"),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          100,150,200,50,
                          hwnd,(HMENU) 1, NULL, NULL);
            break;
        case WM_COMMAND:

            if (LOWORD(wParam) == 1)
            {
                // This is where I assume the operations to get the file name string would be
            }

            break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}


I would really appreciate it if someone could help me with this, I am quite lost and the community here has been very helpful in the past.

Incidentally, if anyone happens to know how to destroy this window and then create a new one automatically, if you could please explain briefly that would be great as well.

Thanks very much,
Ryan
Line 88 is where the text field I would like to read from is created
You can use GetWindowText() to read all the text from an Edit control.

GetWindowText function (Windows)
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633520%28v=vs.85%29.aspx

But it works with a char buffer, so you'll need to read it from the control and then assign it to a std::string afterwards.

Also see

GetWindowTextLength function (Windows)
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633521%28v=vs.85%29.aspx

Andy

PS There is no way to automatically recreate a window using Win32. Given the way you're using your window above, I would use a dialog to obtain the filename instead. And then create the main window after closing the dialog.
Last edited on
Thanks very much for your quick reply,

It doesnt matter to me whether the file name is char[] or string. I can change to an array of characters if that would make it easier.

how would I write the assignment part if I just change: std::string textfilename; to: char textfilename[50];

I looked at the GetWindowText() on msdn, but I dodnt understand what they were talking about :/ it says something about returning the length of the input, but I would have thought it would return the actual input or a pointer to it.

If you could give me a quick example of just how I would assign it to an array, that would be great.

Thanks very much,
Ryan
Oh do I just pass the name of the array as the 2nd parameter?
Yes, the second param is the char array name or char* buffer pointer (TCHAR would be better here, to go with TEXT())

1
2
    TCHAR text[_MAX_PATH] = TEXT("");
    GetWindowText(hwndEdit, text, _countof(text));


Andy

PS _MAX_PATH is defined somewhere in windows.h or one of the headers it includes; it's maximum normal file path (260 chars)

_countof() gives then number of elements of an array (it's a smarter version of sizeof(a)/sizeof(a[0]))
Last edited on
Sorry to bother you again with what is probably a silly question but I cannot get it to compile with hwndEdit as parameter 1... Im really not sure what I am supposed to fill in there.

The error message says "hwndEdit was not declared in this scope".

Thanks,
Ryan
Well, you've forgotten to declare it.

When you call CreateWindow it returns an HWND which you need to keep hold of if you want to communicate with the child window. You've forgotten to do this for all three of your child windows above. I just chose a variable name for illustrative purposes.

Andy
This is what I did:
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
{
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:

            HWND TextFileField;
            HWND FileField;
            HWND OKButtonFileField;

            TextFileField = CreateWindow (TEXT("STATIC"), // User prompt
                         TEXT("Enter the name below of the file you want to open. Include the extension."),
                         WS_VISIBLE | WS_CHILD,
                         10,10,380,50,
                         hwnd, (HMENU) NULL,NULL,NULL
                         );
            FileField = CreateWindow (TEXT("edit"), // box to read the file name from
                          TEXT(""),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          50,100,300,20,
                          hwnd,(HMENU) 2, NULL,NULL);
            OKButtonFileField = CreateWindow (TEXT ("BUTTON"), // This is the ok button, which signifies the user is finished typing the file name
                          TEXT("Ok"),
                          WS_VISIBLE | WS_CHILD | WS_BORDER,
                          100,150,200,50,
                          hwnd,(HMENU) 1, NULL, NULL);
            break;
        case WM_COMMAND:

            if (LOWORD(wParam) == 1)
            {
                GetWindowText(FileField,textfilename,50);
            }

            break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}


Is that right?

Quick question, I am used to working with the console, and the windows API is pretty foreign to me...

Does the GetWindowText function get only the first word (like cin), or the entire line (like cin.getline)?

Thanks very much,
Ryan
I got it all working when I moved the 3 HWND declarations to global... Thank you very much for your help!
Topic archived. No new replies allowed.