VS C++ from the beginning, text box, user input

Pages: 12
hello all, I've been a programmer for 25 years and I'm embarrassed to say, I've never programmed in the windows environment and at this stage in my career I find it a bit overwhelming. Never-the-less I must at this time. So I've downloaded the Visual Studio C++ Express 2010, and on my Windows XP computer loaded it up. I've even found a neat tutorial that at least got me to write my the first "hello world" program using a windows box (To date I always have used just the command line, printf, gets, etc):

snapshot image:
http://jleslie48.com/images/snapshot01_helloworld.jpg


Well it worked, but it is hardly at a point where I'm comfortable with real data processing, or user I/O.

This question/thread deals with how to effectively use this VS C++ environment to make a worthwhile program.

I'd like to modify this code as so:

1) have a user input area such that the user can communicate via the keyboard and send some information (aka I prompt, what is your name? and there is a text box for them to enter it.

2) A message area where I can post some meaningful formatted response. my current output of "hello world \n - jleslie48" did not recognize the \n as a newline.

3) later on if this thread develops, the ability to create other window elements of buttons, drop down lists, etc, will I'm sure be welcome, but lets walk before we run.

TIA

jleslie48.

Oh, here's the code I have so far, I'm not sure the best way on this forum to send up the source code, I created a project called jl02, and it made up a template of sorts, with a bunch of files, the only two I modified were jl02.h and jl02.cpp. I distinguished the code I added vs the template code by preceding my additions with a comment: // mycode jl

here's jl02.h:
1
2
3
4
5
6
7
8
9
10
11
12
////////////////////
#pragma once

#include "resource.h"



//mycode jl
HBRUSH jlwindowBackgroundBrush;
COLORREF jlwindowBackgroundColor;

///////////////////// 



and here is jl02.cpp


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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
///////////////////////
// jl02.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "jl02.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);




/* this is the main entry point */ 

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;


	//mycode jl
	jlwindowBackgroundColor = RGB(0xfa, 0x80, 0x72); 
	jlwindowBackgroundBrush = CreateSolidBrush ( jlwindowBackgroundColor); 


	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_JL02, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_JL02));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_JL02));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
//	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
//	wcex.hbrBackground	= (HBRUSH) (LTGRAY_BRUSH);
	wcex.hbrBackground  = jlwindowBackgroundBrush;
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_JL02);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR helloWorld[] = _T("Hello World!\n - jleslie48");


	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...

		// mycode jl
		  SetBkColor(hdc, jlwindowBackgroundColor);



		TextOut(hdc, 100, 100, helloWorld, _tcslen(helloWorld));



		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}


///////
Last edited on
Hi jleslie48,

I am trying to learn API and here are a couple things that I found very helpful.

1. a. Windows 98 Programming from the ground up
By: Herbert Schildt
ISBN: 0-07-882306-4

Mr. Schildt's attention to detail is outstanding
and he leaves no detail unexplained.
This book really covers how to generate the
skelton frame work to starts windows and
he then tells you step by step how to build
pices and parts such mouse operation, message box,
and every thing else. Excellent book for learning API.

b. Programming Windows Fifth Edition
by: Charles Petzold
ISBN: 1-57231-995-X

Mr. Petzold attention is to how the Windows system
works and he writes some really great examples.
He starts from the basic skelton frame work and
take you through a very through understanding of the Windows system.
His book is consider to be the Bible of API programming.

These two books explain in detail how to program in Windows API. They also have some
outstanding examples of code with complete descriptions of how the code works.

3. There is a source (Microsoft SDK) of all API commands, messages, data types and
how each call function operates. Plus there are some other
very interesting sections that have tools and other items.

I found this to be a great data source for how the call functions
work and what all the messages relate to. There appear to be
1000's of the API commands in this Window API world.

I downloaded the Windows SDK "Windows Server 2008 and .NET Framework 3.5" ISO File and burned it to a DVD.
http://www.microsoft.com/downloads/en/confirmation.aspx?familyId=f26b1aa4-741a-433a-9be5-fa919850bdbf&displayLang=en

The two books and the SDK have turned out to answer almost all of my programing screw ups and questions. These three items have put me on a steady learning path for API.

I hope this will help with your in learning API programming. I can be a lot of fun.

Good luck,

Bill
Well you should write the program from scratch first of all, instead of using the win32 template from microsoft.

you could create a window and procedure in about 80 lines, that template sucks.

Anyway some useful tips that I have are that you can create any control, such as buttons, textboxes, listboxes with the same function you created the window with:

CreateWindowEx

Instead of registering your own class and then creating it, there are predefined ones such as "edit" (textbox) and "button" so, to create a textbox on your main window you can add this code in the window procedure:

1
2
3
4
5
6
7
8
9

switch (message)
    {
        case WM_CREATE:
        {
            CreateWindowEx(NULL, L"Edit", L"Textbox1", WS_VISIBLE | WS_CHILD, 10, 10, 200, 20, hWnd, NULL, g_hInst, NULL);
            break;
        }


That code will create a textbox on your window.

then you can do commands such as

GetWindowText() and SetWindowText() to set and get the text from the textbox

and can also change the L"edit" to L"button" / L"listbox" / L"combobox" etc.. for different controls
Last edited on
Ok, so apparently my project, jl02, I started as a win32 project and this is a little bare bones,

I'm gonna reboot the project using windows forms aka,

New Project...
CLR --> Windows Forms Application

apparently "windows forms application" is the 2010 hiding place for .NET programming.

stay tuned and I'll post my findings with that environment.

ok, jl04_forms works better:

http://jleslie48.com/images/snapshot02_helloworld_forms.jpg


slash n works in the message box, and I've got some kind of gui interface for making the user interface (UI).

Why my code is all in a .h file, who knows. as a C programmer this would of been cardinal sin #1, but hey I'm not gonna deviate from the default yet. My form is also a .h file (they are taking some liberties with what I understood was a ".h" file) and you can see I've got a tab now called
"form.h [Design]" which is some gui thing for laying out a UI. so my next step will be to get rid of that message box, and introduce a scrolling region in my form1 so I can do "printf" debug messages as I go. I'll upload the project if folks want to play along...




.NET is a slow piece of ****, designed for babies to program. use c++ win32 :P

in VS you can go Visual C++ -> Win32 -> Win32 Project, then in the wizard window select empty project and heres a nice very simple win32 app:

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
#include <windows.h>

HINSTANCE ghInst;
const wchar_t* lpClassName = L"WinApp";

#define IDC_BUTTON1		101

HWND hWndTextbox;

// Main window callback function
LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
	case WM_CREATE:
		{
			CreateWindowA("button", "btn1", WS_CHILD | WS_VISIBLE,
				10, 10, 75, 25, hwnd, (HMENU)IDC_BUTTON1, ghInst, NULL);

			hWndTextbox = CreateWindowA("edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE,
				10, 45, 200, 300, hwnd, NULL, ghInst, NULL);

			SetFocus(hWndTextbox);
			break;
		}
	case WM_COMMAND:
		{
			if (LOWORD(wparam) == IDC_BUTTON1)
			{
				MessageBoxA(hwnd, "You clicked button1!", "button1", MB_OK);
			}

			break;
		}
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
			break;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return 0;
}

// Main entry point
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	ghInst = hInstance;
	
	WNDCLASSEX ex;

	ex.cbSize = sizeof(WNDCLASSEX);
	ex.cbClsExtra = 0;
	ex.cbWndExtra = 0;
	ex.hInstance = ghInst;
	ex.style = 0;
	ex.lpszMenuName = NULL;
	ex.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	ex.hCursor = LoadCursor(NULL, IDC_ARROW);
	ex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	ex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	ex.lpszClassName = lpClassName;
	ex.style = NULL;
	ex.lpfnWndProc = mainWndProc;

	RegisterClassEx(&ex);

	HWND hwnd = CreateWindowEx(NULL, lpClassName, L"Windows Application", 
		WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
		200, 200, 500, 500, NULL, NULL, ghInst, NULL);

	ShowWindow(hwnd, nShowCmd);

	MSG msg;

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


thats a template that i created a while ago, though i just added some example controls for you, such as button and textbox.

_________________________________________
quote:
kaije (2) Link to this post Jul 19, 2010 at 4:05pm
.NET is a slow piece of ****, designed for babies to program. use c++ win32 :P

in VS you can go Visual C++ -> Win32 -> Win32 Project, then in the wizard window select empty project and heres a nice very simple win32 app:
...
________________________________________


kaije,


ran like a charm.
that is very impressive, and is wonderfully uncomplicated. I will look at this example very carefully and see how I use it as a basis for teaching myself this environment.


TBC...

I don't think you should use .NET.

It makes your application completely dependent on the .NET framework. If you ever distribute a .NET application, you will have to include a copy of the .NET framework along with it(otherwise your application will not run).

In my opinion it makes your application look very unprofessional.
___________________________
quote:
I don't think you should use .NET.

It makes your application completely dependent on the .NET framework. If you ever distribute a .NET application, you will have to include a copy of the .NET framework along with it(otherwise your application will not run).

In my opinion it makes your application look very unprofessional.
________________________________


Well, for the last 20 years I've done just fine with plain old C, and If I wanted a fancy gui front end I would just use an apache server and cgi. This MS stuff gives me the hives. My company has been using MFC for the past 8 years and I took a look at that. That was a horror. Looks like it was put together by Sybil. We are just in the process of switching over to .net and C#, and the boys say its light years better than MFC with VS 2003.

What do I know, I've never used anything other than gcc and borland 5.5 on a PC.

Anyway, so now I have to use VS and I figured I get up with the times. As practice I want to develop a few fill in boxes, a subfolder selector, a status box where I put printf statements as I process the files, and eventually I will want to put a graph plot of data points.

First up will be to put in a fill in box where I type in my name, and a status scrolling box where my program can printf ("hello %s. how are you today\n",szinputname); Or however VS butchered programming to allow me that most basic programming.

Meantime I could do the whole gui in about 20 lines with callback functions in autohotkey...

Although I have to admit kaije has shown me some very tight code. If I can get some documentation support from msdn so I can expand by reading on this style I would be very happy.

TBC...



Last edited on
Ok, while I'm very impressed with the precise code demonstrated, I'm having trouble "teach myself" to expand on it. I wanted to add the vertical scroll bars to the "edit" textbox. After some time on the web I found the WS_VSCROLL flag, but I was fishing to find. it.

I have also not been able to discover how I write to the text box or read from it. ( I would like a textbox that my program can write to for messages, aka ES_READONLY, but that would create a memory leak if I keep writing to the textbox, without getting rid of previous lines eventually yes?)

My point is two fold,

1) how do acomplish these things,

2) how do find out how to do these types of things without having to post questions every time?

Edit: ok after quite a bit of time I got this far with at least reading the textbox:

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
#define IDC_EDIT01		102


#define LOCALMAXCHAR 2048

HWND hWndTextbox;
 char jlbuffer[LOCALMAXCHAR]; 
// LPWSTR lpedit01buffer = (LPWSTR)jlbuffer; 

// Main window callback function
LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
	case WM_CREATE:
		{
			CreateWindowA("button", "btn1", WS_CHILD | WS_VISIBLE,
				110, 20, 75, 25, hwnd, (HMENU)IDC_BUTTON1, ghInst, NULL);

			hWndTextbox = CreateWindowA("edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE 
				                                      |ES_AUTOVSCROLL |WS_VSCROLL ,
				                                10, 55, 200, 100, hwnd, (HMENU)IDC_EDIT01, ghInst, NULL);

			SetFocus(hWndTextbox);
			break;
		}
	case WM_COMMAND:
		{
			if (LOWORD(wparam) == IDC_BUTTON1)	{
				GetDlgItemText(hwnd, IDC_EDIT01, (LPWSTR)jlbuffer, LOCALMAXCHAR);
//				GetDlgItemText(hwnd, IDC_EDIT01, lpedit01buffer, LOCALMAXCHAR);

//				MessageBoxA(hwnd, "You clicked button1!", "button1", MB_OK);
				MessageBoxA(hwnd, jlbuffer , "button1", MB_OK);

			       } //then IDC_BUTTON1

			break;
		} //case wm_command
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
			break;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return 0;
}


In the debugger I can see that jlbuffer has my characters, but every other character is 0, aka a 16-bit character field. as a result the string only shows 1 character long.

so how can I fix this? I know I'm supposed to use some class thing for string manipulations ...

Last edited on
but that would create a memory leak if I keep writing to the textbox, without getting rid of previous lines eventually yes?


No, Windows takes care of that. Now, if you were to write over 2048 characters(LOCALMAXCHAR) and then call GetDlgItemText(with jlBuffer), your string would be truncated. You should dynamically allocate memory for the text box using the heap and GetWindowTextLength.

MSDN(.com) has every single function in the Win32 API documented. When you want to use another control, search there. Try searching Text Box. You will find every single message, property and function associated with Text Boxes.


In the debugger I can see that jlbuffer has my characters, but every other character is 0, aka a 16-bit character field. as a result the string only shows 1 character long.



Use GetDlgItemTextA, and don't cast to a LPWSTR.

Use GetDlgItemTextA, and don't cast to a LPWSTR.


AHHH!!! of course. I'm living in the xxxxA world not the unicode world. Thank you. I find this very disappointing that VS C++ is not handling this with polymorphism. That was the whole point of C++ in the first place; so that the programmer would not be worried about the underlying mechanism only "the object" It should know at compile time I'm in the Ansi world and use the GetDlgItemTextA instead of xxxW, or xxxES, or whatever.



but that would create a memory leak if I keep writing to the textbox, without getting rid of previous lines eventually yes?

No, Windows takes care of that. Now, if you were to write over 2048 characters(LOCALMAXCHAR) and then call GetDlgItemText(with jlBuffer), ...


Sorry for the confusion. I realize using a textbox as an input box I won't have a memory leak, but worry about a memory leak is if I use a textbox as say for example stderr. I want to make a readonly textbox at the bottom where I can write whatever text I like. As a result the contents of the textbox will continually grow (hence why I wanted the scrollbar.) Ideally I would only hold in the readonly textbox the last say, 1000 lines, of text, throwing out lines in a FIFO (first-in,first-out) fashion.

Ok lets see if I can figure out how to write the buffer to a new readonly textbox, and clear the old one...

TBC.

Thanks again for your support. -JL



Your not using a dialog box, so you can use the calls

SetWindowText(HWND, char*);

and

GetWindowText(HWND, char*, int size);

So for example to display the text of the textbox in a message box:

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

HINSTANCE g_hInst;

HWND hBtn1, hEdit1, hOutput1;
enum { ID_BTN_1=100, ID_EDIT_1, ID_STATIC_1 };

//  This function is called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_CREATE:
        {
            hBtn1 = CreateWindowA("button", "Get text",
                                  WS_CHILD | WS_VISIBLE, 10, 10, 75, 25,
                                  hwnd, (HMENU)ID_BTN_1, g_hInst, NULL);

            hEdit1 = CreateWindowA("edit", "",
                                  WS_BORDER | WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL |
                                  ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL,
                                   10, 45, 300, 300,
                                  hwnd, (HMENU)ID_EDIT_1, g_hInst, NULL);

            hOutput1 = CreateWindowA("static", "output",
                                  WS_CHILD | WS_VISIBLE | SS_CENTER,
                                   10, 355, 300, 25,
                                  hwnd, (HMENU)ID_STATIC_1, g_hInst, NULL);

            SetFocus(hEdit1);

            break;
        }
        case WM_COMMAND:
        {
            switch (LOWORD(wParam))
            {
                case ID_BTN_1:
                {
                    const int size = GetWindowTextLength(hEdit1);

                    char szbuffer[size];
                    GetWindowTextA(hEdit1, szbuffer, size+1);
                    MessageBoxA(hwnd, szbuffer, "Text:", MB_OK | MB_ICONINFORMATION);
                    SetFocus(hEdit1);
                    break;
                }
            }
            break;
        }


Also added a static control, which is just a label, so you can put your output in there, with the SetWindowText call again.

also use http://msdn.microsoft.com/en-us/library and search any function you want, and in VS you can press Ctrl + J in the editor, to display a list of calls which are in the headers you included, or Shift-Ctrl + Space to display the arguments when inside a function
Last edited on
@kaije He is not using a dialog box, but you can still use GetDlgItemText to get the text without have to create a global handle to the text box(if you need the handle to it you can use the GetDlgItem function).
ok vexer and kaije, I'm home now but I can't wait to get back tomorrow and try out kaije's new code.

in the meantime, what do you mean I'm not using a dialog box? I thought my whole program was a dialog box, with a button and an "edit" box. or are you guys referring to a second "pop-up" dialog box??

I was able to successfully add a second "edit" box that was read only and with SetDlgItemTextA was able to write to it. It was not growing log of messages like I wanted, but I could of done that with a char_buffer in my code if I chose. I'll revisit that later.

I am curious about this createwindowA ("static"... textbox with its functions of GetWindow... , SetWindow...

Great demo of enum, and rewrite of WM_COMMAND as a switch statement too. Much more scalable.
dialog boxes are just simple windows created with resource files instead of registering a class and using the CreateWindow function,

heres one from a template on code::blocks

main.cpp
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
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include "resource.h"

HINSTANCE hInst;

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch(uMsg)
    {
        case WM_INITDIALOG:
        {
            /*
             * TODO: Add code to initialize the dialog.
             */
            return TRUE;
        }
        case WM_CLOSE:
        {
            EndDialog(hwndDlg, 0);
            return TRUE;
        }
        case WM_COMMAND:
        {
            switch(LOWORD(wParam))
            {
                /*
                 * TODO: Add more control ID's, when needed.
                 */
                case IDC_BTN_QUIT:
                {
                    EndDialog(hwndDlg, 0);
                    return TRUE;
                }
                case IDC_BTN_TEST:
                {
                    MessageBox(hwndDlg, "You clicked \"Test\" button!", "Information", MB_ICONINFORMATION);
                    return TRUE;
                }
            }
        }
    }

    return FALSE;
}


int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    hInst = hInstance;

    // The user interface is a modal dialog box
    return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
}


resource.rc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "resource.h"

DLG_MAIN DIALOGEX 6, 5, 194, 106

CAPTION "Code::Blocks Template Dialog App"

FONT 8, "Tahoma"

STYLE 0x10CE0804

BEGIN
  CONTROL "&Test", IDC_BTN_TEST, "Button", 0x10010000, 138,  5, 46, 15
  CONTROL "&Quit", IDC_BTN_QUIT, "Button", 0x10010000, 138, 29, 46, 15
END


resource.h
1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>

// ID of Main Dialog
#define DLG_MAIN 101

// ID of Button Controls
#define IDC_BTN_TEST 1001
#define IDC_BTN_QUIT 1002





it compiles the .rc files and then you call the DialogBox function to create it

can also design dialog boxes with some software

http://www.resedit.net/

so you don't have to write the position of the controls in code
kaije,

Please forgive my ignorance, I just looked up "code::blocks" is this an alternate to VS C++ 2010?


you have left code for 3 files, resource.h, resource.rc, and main.cpp

now this looks a lot like the MFC stuff I worked with before, where the resource.rc file was some kind of derivation from a gui layout editor. Am I supposed to take these 3 files and start a new project with them?

I find this very disappointing that VS C++ is not handling this with polymorphism.


I'd like to mention that VS C++ is completely separate from the Win 32 API. VS C++ is a Compiler along with an IDE. Any compiler can compile Win 32 API code as long as you use the correct header files. Also, the Win 32 API was designed for C, hence it is not object oriented and uses simple structures for things like window classes.

Please forgive my ignorance, I just looked up "code::blocks" is this an alternate to VS C++ 2010?


It's just another IDE with a compiler, it basically does the same thing as VS C++, but it is designed differently(and looks different).
OK,

SetWindowTextA did not work on a CreateWindowA("static", "output", . However it diid work fine on a CreateWindowA("edit", "output", ... | ES_READONLY which should be just as effective. See program below, at or about lines 30 and 49

So what is the difference between GetWindowTextA/ SetwindowTextA vs. GetDlgItemTextA/SetDlgItemTextA?


complete program with xxxWindowTextA,
main.cpp:
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
#include <windows.h>

HINSTANCE ghInst;
const wchar_t* lpClassName = L"WinApp";

#define LOCAL_MAXBUFFER   2048

HWND hBtn1, hEdit1, hOutput1;
enum { ID_BTN_1=100, ID_EDIT_1, ID_STATIC_1 };



// Main window callback function
LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
	case WM_CREATE:
		{
            hBtn1 = CreateWindowA("button", "Get text",
                                  WS_CHILD | WS_VISIBLE, 10, 10, 75, 25,
                                  hwnd, (HMENU)ID_BTN_1, ghInst, NULL);

            hEdit1 = CreateWindowA("edit", "",
                                  WS_BORDER | WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL |
                                  ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL,
                                   10, 45, 300, 300,
                                  hwnd, (HMENU)ID_EDIT_1, ghInst, NULL);

            hOutput1 = CreateWindowA("edit", "output",
                                  WS_CHILD | WS_VISIBLE | ES_MULTILINE | ES_AUTOHSCROLL |
                                  ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL | ES_READONLY,
                                   10, 355, 300, 225,
                                  hwnd, (HMENU)ID_STATIC_1, ghInst, NULL);

            SetFocus(hEdit1);

            break;
  
		} //WM_CREATE
	case WM_COMMAND:
		{
            switch (LOWORD(wparam)) {
                case ID_BTN_1:  {
                    const int size = GetWindowTextLength(hEdit1);

                    char szbuffer[LOCAL_MAXBUFFER];
                    GetWindowTextA(hEdit1, szbuffer, size+1);
		    SetWindowTextA(hOutput1, szbuffer ); 
                    MessageBoxA(hwnd, szbuffer, "Text:", MB_OK | MB_ICONINFORMATION);
                    SetFocus(hEdit1);
                    break;
                    } //ID_BTN_1
                } //switch wParam


			break;
		} //WM_CREATE
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
			break;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		return DefWindowProc(hwnd, msg, wparam, lparam);
	} // switch msg

	return 0;
}

// Main entry point
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	ghInst = hInstance;
	
	WNDCLASSEX ex;

	ex.cbSize = sizeof(WNDCLASSEX);
	ex.cbClsExtra = 0;
	ex.cbWndExtra = 0;
	ex.hInstance = ghInst;
	ex.style = 0;
	ex.lpszMenuName = NULL;
	ex.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	ex.hCursor = LoadCursor(NULL, IDC_ARROW);
	ex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	ex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	ex.lpszClassName = lpClassName;
	ex.style = NULL;
	ex.lpfnWndProc = mainWndProc;

	RegisterClassEx(&ex);

	HWND hwnd = CreateWindowEx(NULL, lpClassName, L"Windows Application", 
		WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
		200, 200, 500, 700, NULL, NULL, ghInst, NULL);

	ShowWindow(hwnd, nShowCmd);

	MSG msg;

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}




complete program with xxxDlgItemTextA,
main.cpp:
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
#include <windows.h>




HINSTANCE ghInst;
const wchar_t* lpClassName = L"WinApp";


#define IDC_BUTTON1		101
#define IDC_EDIT01		102
#define IDC_EDIT02		103



#define LOCALMAXCHAR 2048

HWND hWndTextbox;
HWND hWndTextbox_output;

char jlbuffer[LOCALMAXCHAR]; 

// Main window callback function
LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch (msg)
	{
	case WM_CREATE:
		{
			CreateWindowA("button", "btn1", WS_CHILD | WS_VISIBLE,
				110, 20, 75, 25, hwnd, (HMENU)IDC_BUTTON1, ghInst, NULL);

			hWndTextbox = CreateWindowA("edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE 
				                                      |ES_AUTOVSCROLL |WS_VSCROLL ,
				                                10, 55, 400, 100, hwnd, (HMENU)IDC_EDIT01, ghInst, NULL);
			hWndTextbox_output = CreateWindowA("edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE 
				                                      |ES_AUTOVSCROLL |WS_VSCROLL | ES_READONLY ,
				                                10, 290, 400, 100, hwnd, (HMENU)IDC_EDIT02, ghInst, NULL);
			SetFocus(hWndTextbox);
			break;
		}
	case WM_COMMAND:
		{
			if (LOWORD(wparam) == IDC_BUTTON1)	{
				GetDlgItemTextA(hwnd, IDC_EDIT01, jlbuffer, LOCALMAXCHAR);
				
				SetDlgItemTextA(hwnd, IDC_EDIT02, jlbuffer);
				SetDlgItemTextA(hwnd, IDC_EDIT01, "");

				MessageBoxA(hwnd, jlbuffer , "button1", MB_OK);

			    } //then IDC_BUTTON1

			break;
		} //case wm_command
	case WM_CLOSE:
		{
			DestroyWindow(hwnd);
			break;
		}
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	default:
		return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return 0;
}

// Main entry point
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	ghInst = hInstance;
	
	WNDCLASSEX ex;

	ex.cbSize = sizeof(WNDCLASSEX);
	ex.cbClsExtra = 0;
	ex.cbWndExtra = 0;
	ex.hInstance = ghInst;
	ex.style = 0;
	ex.lpszMenuName = NULL;
	ex.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	ex.hCursor = LoadCursor(NULL, IDC_ARROW);
	ex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	ex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	ex.lpszClassName = lpClassName;
	ex.style = NULL;
	ex.lpfnWndProc = mainWndProc;

	RegisterClassEx(&ex);

	HWND hwnd = CreateWindowEx(NULL, lpClassName, L"Jon's Windows Application", 
		WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
		200, 200, 500, 500, NULL, NULL, ghInst, NULL);

	ShowWindow(hwnd, nShowCmd);

	MSG msg;

	while(GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}
heres one from a template on code::blocks

main.cpp...


Well I tried to make this into a project, using Visual C++ -> Win32 -> Win32 Project, empty project option,

I was able to make main.cpp, but when I went to the Resource files, to make resource.rc, it converted my project tol CLR, and made up a resource.cpp and a resource.h. Resource.h is labled in the IDE as a tab: resource.h [Design] and is some gui thing. I'm not sure how to turn these 3 files into a project.

here's a snapshot:

http://jleslie48.com/images/snapshot03_code_block.jpg

Last edited on
Pages: 12