I have a simple program that I am having trouble debugging.
It contains two different problems.

1. If I run a MessageBox in this program after the program is
up and running, the program crashes. I have to call the
Task Manager to shut down the program.

2. SetTimer will not work unless I put other code in the
funtion containing it. I've pinned down what happens using
a debugger but don't know how to cure it. I'm popping BPX
with a bad momory position after SetTimer completes.

The program is in working order now by fudging and the
"points of failure" are documented in the program.
I tried to eliminate compiler problems by compiling
using two different compilers. "cl" and Borland BCC.
Both act the same.

I run an AMD with SP1.

Recommended Answers

All 8 Replies

Hint: If the code in the timer proc TimerProc() takes more time to execute than the amount of time specified in the SetTimer() function call (1 second) then TimerProc() needs to kill the timer and restart it before leaving. Don't leave the timer running or the os will call TimerProc() again before it has finished processing the previous call. That can be disasterous.

I blocked off the print text code in the time function and then raised the time to 10 seconds. Thaat failed. Then I killed the timer in the procedure as you suggested. That failed. Maybe I am not understanding what you suggest correctly. Please clarify.

I've been doing some experiments while waiting for further replies.

If I move the two timer functions above the "DoMenu" function, then MessageBox will work. I don't know why but you can't beat success.

If I block off the TextOut portion inside the SetTimer it still does not work even with both functions above the DoMenu.

I have compiled and run your program several times and I can't get SetTimer() to work either. I even started a whole new simple win32 api program that the compiler generated, and SetTimer() doesn't work there either. Finally tried google search for the problem -- other people have had the same problem but I didn't see any solutions!

The only way I could make it work is like this, which is almost the same as you originally posted. And I think I would just leave it like that.

HWND MyTimerFunc(HWND hwndMainFrame)
{          // *************************************** START TIMER
   HDC  hDC;
   PAINTSTRUCT paintStruct;

   hDC = GetDC(hwndMainFrame);
    BeginPaint(hwndMainFrame, &paintStruct);
    SetTimer(NULL,0,1000,(TIMERPROC)TimerProc);
// ----- Remove below and the function fails --------------------------- TEST INFO
    //TextOut(hDC,1,20,"MyTimerFunc has been called.",28);
    EndPaint(hwndMainFrame, &paintStruct);
    ReleaseDC(hwndMainFrame, hDC);
// ----- Keep above and fuction works ---------------------------- TEST INFO

    return 0;
}          // ********************************* END TIMER

Using BeginPaint() ad-hoc like this isn't recommended. Works sometimes, but isn't reliable. You should only use it in response to WM_PAINT messages.
Your WM_PAINT handler does nothing, so I suggest you add something like this to MainWndProc():-

case WM_PAINT:
{
 	PAINTSTRUCT ps;
	HDC hdc;
	hdc = BeginPaint(hwndMainFrame, &ps); 
        // Do your painting
	EndPaint(hwndMainFrame, &ps); 
        return 0L; 
}

Even if you don't want to paint anything right now, put in the Begin and EndPaint() calls.
With that in place, remove all the painting code from MyTimerFunc() and TimerProc() and just use message boxes where necessary.
If you want to use TextOut(), do it in response to WM_PAINT rather than when the fancy takes you.

After these changes I think your timer will behave normally.

To Ancient Dragon:

I appreciate all the work you did. I've been working on it too. Without the paint sequence, the stack loads differently. It seems the compiler leaves out one line of code "POP EBX". This causes the stack to get one less line.

I hate to have a program with a fudge like this. I use this little program as a blank to compile various api's so I can see them in assembly.

If you've given up, I will too and just keep the fudge in.

toolmanx@ij.net

The timer doesn't work without the paint code in MyTimerFunc() because you don't handle WM_PAINT, so the window is not validated and the high frequency (and priority) of WM_PAINT messages blocks the low priority WM_TIMER message.
Just handle WM_PAINT as suggested and your timer will work without the misplaced painting.
I don't understand why you were getting crashes when calling MessageBox() however.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.