🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
3 messages
3 total messages Started by UO Sat, 12 Apr 2008 08:54
WM_TIMER / WM_PAINT
#428
Author: UO
Date: Sat, 12 Apr 2008 08:54
82 lines
2812 bytes
Hi,

Consider the following code:

// 1
int g_cnt;

    case WM_CREATE:
        SetTimer(hwnd, IDTIMER0, 20, NULL);
        g_cnt = 0;
    break;

    case WM_TIMER:
        g_cnt++;
        if(g_cnt > 1)
            Messagebox(hwnd, "g_cnt > 1", "info", MB_OK); //A
        SomeCode(); // takes 100ms time.
        g_cnt--;
    break;

After creating the window, because the code in "case WM_TIMER:" takes more 
time than the
poll time of the timer, do WM_TIMER messages fill the message queue buffer 
in the end? I've noticed,
the line marked with "A" never executes, that means g_cnt is never greater 
than one.

Now consider the following code:

// 2
char buf[100];
int g_cnt;

    case WM_TIMER:
        g_cnt++;
            sprintf(buf, "g_cnt=%d", g_cnt);
            MessageBox(hwnd, buf, "info", MB_OK); //B
        g_cnt--;
    break;

Here, g_cnt increases with the display of every MessageBox.
After g_cnt reaches approx. 650, the program displays an "Access Violation" 
(in PC);
The limit "650" is only "45" in my embedded device powered with WindowsCE.
What is the difference between Code //1 and Code //2 ?

Another question, consider the following code:
//3

RECT rect;
PAINTSTRUCT ps;
HDC hdc;

    case WM_CREATE:
        SetTimer(hwnd, IDTIMER0, 20, NULL);
        cnt = 0;
        GetClientRect(hwnd, &rect);
    break;

    case WM_TIMER:
        KillTimer(hwnd, IDTIMER0);

        //Do some coordinate-calculations for the objects that are displayed 
in WM_PAINT:

        InvalidateRect(hwnd, &rect, FALSE);
        SetTimer(hwnd, IDTIMER0, 20, NULL);
    break;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);
        //DisplayObjects();
        EndPaint(hdc, &ps);
    break;

I've never noticed that "case WM_TIMER:" and "case WM_PAINT:" are executed
simultanously. Is it always true in this case? I have to be sure because it 
would be
disaster if the coordinates of the objects are changed while they are 
displayed.

Thanks...
Re: WM_TIMER / WM_PAINT
#431
Author: Bob Gonder
Date: Sun, 13 Apr 2008 00:01
72 lines
3236 bytes
UO wrote:


>After creating the window, because the code in "case WM_TIMER:" takes more 
>time than the poll time of the timer,

Then you need to increase the timer amount.

> do WM_TIMER messages fill the message queue buffer in the end?

I think so.
Another thing to try is to show the elapsed time between WM_TIMER.
Vary the code so it stalls for a while,
then bypasses to zip through any backlog.
Take note of the time, especially if it is less than the Timer amount.

> I've noticed, the line marked with "A" never executes, that means g_cnt is never greater 
>than one.

They run sequentially, so the counter never varies.

>    case WM_TIMER:
>        g_cnt++;
>            sprintf(buf, "g_cnt=%d", g_cnt);
>            MessageBox(hwnd, buf, "info", MB_OK); //B
>        g_cnt--;
>    break;
>
>What is the difference between Code //1 and Code //2 ?

Well, Code 2 calls MessageBox every time while Code 1 never does.
Seems obvious that MessageBox is processing messages.
As a further test, add another counter and display it on your Form.

        g_cnt++;
        g_cnt2++;
            sprintf(buf, "g_cnt=%d  g_cnt2=%d", g_cnt, g_cnt2);
		Form1->Label1.SetTextBuf( buf );
        g_cnt--;

Win32API alternative to VCL SetTextBuffer is
	SendDlgItemMessage( hwnd, nIDDlgItem, WM_SETTEXT, 0, (LPARAM)buf );
 
You should see cnt2 increase while cnt1 remains 1.

>I've never noticed that "case WM_TIMER:" and "case WM_PAINT:" are executed
>simultanously. Is it always true in this case?

Yes.
Messages all happen sequentially in the main thread.
This isn't an interrupt system.
The thread that owns the window executes each message in the queue.

What you were seeing with MessageBox was the main thread
processing WM_TIMER, then running/processing MessageBox,
processing WM_TIMER within that window, then recursing on
down until the stack or resources run out.

The way you get around that is to guard the code:
>    case WM_TIMER:
	if( 0 == g_cnt )
	{
	    ++g_cnt;
            sprintf(buf, "g_cnt=%d", g_cnt);
            MessageBox(hwnd, buf, "info", MB_OK); //B
	    --g_cnt;
	};
>    break;


Multithreaded apps however, can be working on different
messages, just not for the same form instance.
Re: WM_TIMER / WM_PAINT
#437
Author: Remy Lebeau (TeamB)
Date: Mon, 14 Apr 2008 17:02
12 lines
1443 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message 
news:2rg204ln4b2t3hulvbbg5k3jq79ql01ioh@4ax.com...

> Seems obvious that MessageBox is processing messages.

Yes, it does.  It is showing a modal dialog.  Since the calling thread's 
message queue is blocked until MessageBox() exits, MessageBox() has to run 
its own message queue internally so the user can interact with the dialog.


Gambit 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads