Make a counter that increments slowly and show it in one place.?

The best I could come up with is this.

1
2
3
4
5
 while(true){
	wisdomCnt++;
	_stprintf_s(szBuffer, _T("%i"), wisdomCnt/10000);
	TextOut(hdc,120,10,szBuffer, _tcslen(space));
}


but the program is constantly loading and clicking anywhere causes it to stop responding. Is there a better way to do this especially in Win32 API?
Last edited on
You could thread a function instead of using a tick counter.

1
2
3
4
5
6
7
8
9
10
11
#include <thread>
#include <chrono>

void slow_inc(int &r, bool &predicate)
{
    while (predicate)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        ++r;
    }
}
Hmm thanks! I've only just finished Intro to Comp Sci and I'm trying to tackle the win32 API on my own. Haven't heard of thread (in regards to programming yet) I'll look into this.
This question looks like it should be moved across to the Windows forum?

As you're using TextOut, I assume you're talking about a Windows GUI app. In that case, the usual way would be to use a timer and handle the count using the message loop.

- use SetTimer() to start the timer
- use KillTimer() to stop the time
- handle WM_TIMER to update the count and than call InvalidateRect to force the window to redraw: no drawing is done here
- do all your drawing in your WM_PAINT handler

As an optimization you can invalidate only the region where your count is displayed. Then you have to use the GetUpdateRect function to check what needs to be repainted (just the the counter value, or the whole of the window).

See

Timers
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632592%28v=vs.85%29.aspx

Andy
So I've tried to create a timer but I can't seem to get it to display. What am I missing?

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
	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);
		 TextOut(hdc, 10, 10, greeting, _tcslen(greeting));
		 // while(true){
SetTimer(hWnd,             // handle to main window 
    IDT_TIMER1,            // timer identifier 
    10000,                 // 10-second interval 
    (TIMERPROC) NULL); 
	case WM_TIMER: 
 
		switch (wParam) { 
			case IDT_TIMER1: 
            // process the 10-second timer 
 
             return 0; 
			 break; 
		}
			 // wisdomCnt++;
		 _stprintf_s(szBuffer, _T("%i"), wisdomCnt);
		 TextOut(hdc,120,10,szBuffer, _tcslen(space));
		 // }

		  
  //MessageBox(hWnd, szBuffer, _T("wat"), MB_OK);
		// TODO: Add any drawing code here...

		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	HWND hwndTimer=0;   // handle to window for timer messages 
MSG msg;          // message structure 
 
    while (GetMessage(&msg, // message structure 
            NULL,           // handle to window to receive the message 
               0,           // lowest message to examine 
               0))          // highest message to examine 
    { 
 
        // Post WM_TIMER messages to the hwndTimer procedure. 
 
        if (msg.message == WM_TIMER) 
        { 
            msg.hwnd = hwndTimer; 
        } 
 
        TranslateMessage(&msg); // translates virtual-key codes 
        DispatchMessage(&msg);  // dispatches message to window 
    } 
	return 0;
}
Here is my updated code. Should make more sense now. But I still not sure how to get my variable to increment with the timer?

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
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	TCHAR greeting[] = _T("Wisdom Earned:");
	TCHAR space[] = _T("  ");
	_TCHAR szBuffer[100];
	int wisdomCnt=0; 
	UINT_PTR  IDT_TIMER1=1;
	static BOOL fFlipFlop = FALSE ;
        RECT rc;


	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_CREATE:
          SetTimer (hWnd, IDT_TIMER1, 1000, NULL) ;
		  return 0 ;
	case WM_TIMER :
          wisdomCnt++;    
          fFlipFlop = !fFlipFlop ;
          InvalidateRect (hWnd, NULL, FALSE) ;
          return 0 ;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		 TextOut(hdc, 10, 10, greeting, _tcslen(greeting));
		 _stprintf_s(szBuffer, _T("%i"), wisdomCnt);
		 TextOut(hdc,120,10,szBuffer, _tcslen(space));
		
		//MessageBox(hWnd, szBuffer, _T("wat"), MB_OK);
		// TODO: Add any drawing code here...
		GetClientRect (hWnd, &rc) ;


		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		KillTimer (hWnd, IDT_TIMER1);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	
	return 0;
}
Last edited on
SWEET IT WORKS GUYS! Thanks for sending me in the right direction. All I had to do was set my variable to static. Not sure why, but it works.

I let it run, seems like I need to designate more space if i want it to show more numbers. But if I designate more space I get odd visual corruption in the spaces that don't have anything. Looking into it.

http://img.techpowerup.org/130509/demo.png
Last edited on
Topic archived. No new replies allowed.