A few questions.

Ok, this may seem stupid to some of you. But I'm teaching myself how to make Win32 apps for the first time, I only started today!

I've made a basic window and now I want to use a class. Where do I create the object in the code?

I ask this, because I have an edit box, which when I type in too, I want the remaining chars available to go down.

on the call of WndProc() I create an object of my class.
myClass c;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case WM_COMMAND:
	{
		switch(LOWORD(wParam))
		{
			case IDC_QUIT_BUTTON:
				{
					PostQuitMessage(0);
					break;
				}

				case ID_EDITBOX_IN:
				{
					c.setCharCount( c.getCharCount() - 1 );
					InvalidateRect( hWnd, NULL, true );
					break;
				}

		}

		break;
	}


I guess I'm going out of scope, and recreating the object each call. As there's no loop in WndProc. So where does WndProc get called from. Main:
while (GetMessage(&msg, NULL, 0, 0)) ?

Also, is it necessary to redraw the screen, each value change? If so, is this the best way to do it?
InvalidateRect( hWnd, NULL, true );


Thanks for any help given!
Declare the class variable globally and initialize it (if it requires initialization) in WinMain().
Thanks! I thought about doing it like that.

But was always told that was bad. Atleast in Win Console Apps, I suppose. ahaha.

I was always told it was bad practise to use global variables. And since I started learning Win32 Apps today, I've used more global variables than ever before!
It is not really bad per se. The problem is that noobs abuse them. As you get more practice with OOP you'll get better and better and rely less and less on globally-scoped variables, but there are instancse where you just can't escape them.

...but there are instancse where you just can't escape them.


They are very, very rare (I've found one instance in 11 years of Win32 coding). I feel there are fewer reasons to use them in GUI apps than in Console apps. However, I can sympathsize with someone just learning Win32. It is difficult. For that reason I would highly recommend getting a copy of Petzold's "Programming Windows" to put everything in perspective and show the right way to do things.
I've seen in my own code where I could not figure out any way to not use a global variable, only to have some real expert show me how to use pointers so as to avoid global scope, but it is usually quite complicated so I've resigned myself to using globals when I feel that I am forced to use them, but as was stated earlier, as I get better and better at it I'm sure that I will need them less.
Thanks for the info fellas. And Freddie, I'll be keeping an eye out for that book, have to go town tomorrow!

Anyone got any info on redrawing the screen?

I'm using an Edit box, and each time the user adds/subtracts a key, I change the variable for the remaining characters. This is a bit of a problem, as when you type fast/hold a key, you can see the redrawing with the following line:

InvalidateRect( hWnd, NULL, true );

1
2
3
4
5
6
7
8
9
case ID_EDITBOX_IN:
	{
		c.setCharCount( szMessage - Edit_GetTextLength( hwndEditIn ) );

		//redraw the window
		InvalidateRect( hWnd, NULL, true );
								
		break;
	}
Lynx, I'm lost with your code. You aren't showing enough of it for anyone to provide concrete help. What in the world is c? And as far as your description of your problem, I can't follow. Can you give a high level description of what you are trying to accomplish? I know it is VERY clear in your mind, but not for others. For example, are you trying to learn how to put text in a text box, i.e., edit control? That's what I mean by high level description of what you are trying to do.

Also, you won't find Petzold 'downtown'. Its an old book, but valuable and still pertinent. You would need to check out Barnes & Nobles, Amazon, etc.
Ok, so, I'm making this:
http://i749.photobucket.com/albums/xx132/Bigdave876/Cpp/cc-1.jpg

Each time I type in the top edit control, I change a global variable( c is the object, of the class which holds the variable ), of the total characters in the box. And as far as I know, I have to redraw the window to update the variable shown in the window.

Is the line InvalidateRect( hWnd, NULL, true );, the best/most efficeint way of updating this?

I've taken irrelevant code out to keep the post short.
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
//I create a global object of 'c' above main

case WM_CREATE:
			{
				//Edit_Control_IN
				hwndEditIn = CreateWindowEx( 0, L"EDIT",
                                                                NULL,
                                                                WS_CHILD | WS_VISIBLE | 
                                                                ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 
                                                                eCenterX,
								ePosY,
								eWidth,
								eHeight,
                                                                hWnd,
                                                                (HMENU) ID_EDITBOX_IN,
                                                                (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), 
                                                                NULL);
 
				// Add text to the window. 
				SendMessage(hwndEditIn, WM_SETTEXT, 0, (LPARAM) inText);


				//Edit_Control_OUT
				HWND hwndEditOut = CreateWindowEx( 0, L"EDIT",
                                                                NULL,
                                                                WS_CHILD | WS_VISIBLE | ES_READONLY |
                                                                ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL, 
                                                                eCenterX,
								ePosY + ( eHeight + 30 ),
								eWidth,
								eHeight,
                                                                hWnd,
                                                                (HMENU) ID_EDITBOX_OUT,
                                                                (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE), 
                                                                NULL);

				// Add text to the window. 
				SendMessage(hwndEditOut, WM_SETTEXT, 0, (LPARAM)outText );
				
				c.setCharCount( szMessage - Edit_GetTextLength( hwndEditIn ) );

				break;
			}

			case WM_COMMAND:
				{
					switch(LOWORD(wParam))
					{
						//buttons
						case IDC_QUIT_BUTTON:
							{
								PostQuitMessage(0);
								break;
							}

						//edit control
						case ID_EDITBOX_IN:
							{
								c.setCharCount( szMessage - Edit_GetTextLength( hwndEditIn ) );

								//redraw the window
								InvalidateRect( hWnd, NULL, true );
								
								break;
							}
					}
					break;
				}
I am not totally sure on what your doing here, but from the picture it looks like you made a Windows Form and setup a GUI for it and I am assuming its flickering. Might I suggest Buffering. Or in some cases its known as Double Buffering depending on what your doing. This will prevent the screen from flickering when you type.

http://msdn.microsoft.com/en-us/library/b367a457.aspx

I hope any of this info helps.
Last edited on
Thanks for the picture Lynx. I think I know what you are trying to do now. You want an upper and a lower text box. After the user types something in the upper text box, the user can click a button to perform some kind of operation on the text in the upper text box and display the result of that operation in the lower text box???

If I have it right, it doesn't seem to make much sense what you are doing. When a text box has focus and the user is typing characters into it, you don't have to take any action whatsoever in your code for all this to happen. In any case, if you did want to take some action on each keypress the user was making while the focus was in a textbox, you would need to subclass the textbox to gain access to the internal window procedure of the textbox, which you don't have in your application.

Unless I have it all wrong in terms of what you are trying to do, all you need are your two CreateWindow() calls in your WM_CREATE handler to create your two edit controls, and CreateWindow() calls for your buttons. When the user clicks a button you can call GetWindowText() to get the text out of the top text box, do whatever you want with that text, and write it back to the lower text box with SetWindowText().
Thanks for the help!


@WinwordExonar
Yes, that's what I need. I've been looking for a while now and tried to implement it, but to no avail. I'm not sure if I'm doing it correctly. Here's 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
35
36
37
38
case WM_PAINT:
			{
				PAINTSTRUCT ps;
				HDC hdc = GetDC( hWnd );
				HDC memDC = CreateCompatibleDC( hdc );

				memDC = BeginPaint(hWnd, &ps);
				// TODO: Add any drawing code here...

				//get text
				SelectObject (memDC, titleText);
				SetBkMode (memDC, TRANSPARENT);

				//title
				TextOut( memDC, 20, 3, aTitle, _tcslen( aTitle ) );

				//set up a buffer for the charCount
				TCHAR buff[ 5 ];

				//select smaller text
				SelectObject (memDC, text);

				//show copyright info
				TextOut( memDC, 620, ( wHeight - 50 ), copyRight, _tcslen( copyRight ) );

				//show chars left text
				TextOut( memDC, 9, ( eHeight + 50 ), charsLeft, _tcslen( charsLeft ) );
				TextOut( memDC, 100, ( eHeight + 50 ), buff, wsprintf( buff, L"%d", c.getCharCount() ) );

				//draw to the window
				BitBlt( hdc, 0, 0, 0, 0, memDC, 0, 0, SRCCOPY );

				ReleaseDC( hWnd, hdc );
				DeleteDC( memDC );

				EndPaint(hWnd, &ps);
				break;
			}


@freddie1
The only thing I need the edit box to do is this:
1
2
3
4
c.setCharCount( szMessage - Edit_GetTextLength( hwndEditIn ) );

//redraw the window
InvalidateRect( hWnd, NULL, true );


Just change the variable based on the total amount of chars in the box and redraw the window.
The bottom box is 'read only' so that you can see the text that was encrypted/decrypted.

Anyway, I have all this working fine now. The only thing I can't seem to get passed, is the flickering of the screen.

EDIT:
Just realised BitBlt is for images :/ lol.
Last edited on
Glad I could help. You will need to know how to set it up before you actually do anything :

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.doublebuffered.aspx#Y0

It will show you on that page the C++ source code example.
Last edited on
I've seen that link a few times while trying to get this to work, lol. This may be a noob question to you, but how do I actually implement that code, so I can set the bool?

Do I need to create a class or something to do it? Could you provide an example, if possible?

And thanks for the help!

EDIT:
By the way, I'm creating a Win32 App within VS2010, not a Windows Form.
Last edited on
There are various tricks to avoiding a global window object. One that is quite straightforward, and has been discussed quite a bit on this site, it to create your window object using new and then store the pointer using SetWindowLongPtr + GWL_USERDATA.

You have to register a special WindowProc which more or less just gets the pointer back using GetWindowLongPtr and then calls the ProcessMessage (or whatever) method of the instance (I then usually code a method which just routes the message to the appropriate handler),

There is bit of a trick to hook things up, but once it's up and running, everything is nice and encapsulated.

If you're interested, search for GetWindowLongPtr + GWL_USERDATA + WM_NCCREATE. You'll find assorted discussions, including those on this site.

Andy
Last edited on
Topic archived. No new replies allowed.