SetTimer works only when I minimize SDI?

skosche3
skosche3 used Ask the Experts™
on
I am using a SDI with a splitscreen.  One side is where OpenGL renders and the other is a FormView dialog.  I am trying to place a timer in the dialog class called FormCommandView.  I want the timer to call functions that gather data from the parallel port every 10ms.  I tried using the TimerProc below since the class is derived from FormView and not CWnd.

VOID CALLBACK MyTimerProc(
 HWND hWnd,     // handle of window for timer messages
 UINT uMsg,     // WM_TIMER message
 UINT idEvent,  // timer identifier
 DWORD dwTime   // current system time
)
{
...MessageBox
}

SetTimer(1,10,(TIMERPROC) MyTimerProc);

I tried opening a MessageBox to test if the timer was workng and I also stepped through the debugger.

I noticed that it only goes into MyTimerProc when I minimized my SDI and when I maxmize the SDI it stops once again.  So the timer only works when my application is minimized.

Can anyone tell me why this is happening and how to fix it.  Is it because I am not passing in my hwnd from the View class where OpenGL is setup.  If so, how do I gain access to it.

Or if you can think of anoter way to use SetTimer with a SDI, please let me know.  I just need to access the parallel port faster because without a timer, my program can not update the screen and go back through my loop fast enough to catch the switching data.

THanks
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
The possible reason for this is that when your window is not minimized the program is very busy. What happens in your drawing code? What is the loop you are talking about? Try to call VB-like function DoEvents from your loop which possibly takes a long time to execute:

while(...)
{
   ...
   DoEvents();
}

void DoEvents()
{
    MSG msg;
   
    while ( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE ) )
    {  
        if ( ::GetMessage(&msg, NULL, 0, 0))
        {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
        else
            break;
    }
}

You cal also use additional parameters of PeekMessage and GetMessage to specify what messages you want to handle.

Author

Commented:
I have noticed that in my drawing code, if
"Invalidate(FALSE)" is not present in the OnPaint function below, that OnTimer almost works correctly and Messageboxes now appear without minimizing.  The problem is without it, my screen does not update accordingly(at all,unless i resize the screen).  And with it I have noticed that my CPU stays at 100% as it continues to loop through OnPaint not allowing other messages to get through.  

Also you asked about my loop:  Right now i use ProcessData at the end of OnPaint which has functions to call on the parallel port.  This is a loop that the message map creates by constantly calling WM_PAINT.  Though I can not read data faster than 150ms before I miss some data.  Therefore when I press the "START SIMULATION" button in the dialog box of the second split screen, I would like Settimer to be called creating a message map so that data is collected every 10ms from the Parallel Port, then continue with processing the OnPaints.

If I was to use your code above, where would I implement it?????  THanks for you help

void CS2TAView::OnPaint()
{
     CPaintDC dc(this); // device context for painting

     // TODO: Add your message handler code here
     CS2TADatabase* pDoc = GetDocument();
       
     pDoc->RenderScene();
     SwapBuffers(dc.m_ps.hdc);
     Invalidate(FALSE);

     Form->ProcessData();
     // Do not call CView::OnPaint() for painting messages
}
Commented:
Using Invalidate or UpdateWindow in OnPaint causes endless loop because OnPaint is called again as result of these functions.

I didn't understand exactly your explanation about ProcessData. General approach for paint messages is:
1) OnPaint function shows information according to current program state
2) Every time program state is changed, call
Invalidate();
UpdateWindow();
and OnPaint function is called by Windows when it is possible. It redraws your window according to new program state.
3) OnPaint function should be fast and contain only drawing code.

I hope this helps. Give me more information if needed.

Author

Commented:
Thanks AlexFM, your comments were exactly what I needed to find my solution.  

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial