Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Error when firing SetTimer in a Modeless Dlg

Error when firing SetTimer in a Modeless Dlg

Scheduled Pinned Locked Moved C / C++ / MFC
data-structuresdebuggingregexhelpquestion
11 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RobJones
    wrote on last edited by
    #1

    Hello all, I have created a dialog type app.. I have a modeless dlg box that needs to run a timer, the reason it's Modeless is the timer needs to be active all the time even when the Dialog box it hidden (I'm checking if the timer is equal to a int every second, when they match I run a event).. I added the WM_TIMER function to this Modeless dialog.. When I fire the "OnTimer(UINT nIDEvent)" by doing a "SetTimer(IDC_S_TIMER1,1000,NULL);" from another control, I get the following error in debug mode: First-chance exception in Dialog.exe: 0xC00000FD: Stack Overflow. And it points to OnTimer(UINT nIDEvent) ->{ Any ideas why? :) Thanks, RobJones

    S A 2 Replies Last reply
    0
    • R RobJones

      Hello all, I have created a dialog type app.. I have a modeless dlg box that needs to run a timer, the reason it's Modeless is the timer needs to be active all the time even when the Dialog box it hidden (I'm checking if the timer is equal to a int every second, when they match I run a event).. I added the WM_TIMER function to this Modeless dialog.. When I fire the "OnTimer(UINT nIDEvent)" by doing a "SetTimer(IDC_S_TIMER1,1000,NULL);" from another control, I get the following error in debug mode: First-chance exception in Dialog.exe: 0xC00000FD: Stack Overflow. And it points to OnTimer(UINT nIDEvent) ->{ Any ideas why? :) Thanks, RobJones

      S Offline
      S Offline
      Steen Krogsgaard
      wrote on last edited by
      #2

      The stack overflow could be caused by recursive calling OnTimer(UINT nIDEvent). How does the call stack look after the exception? Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

      R 1 Reply Last reply
      0
      • S Steen Krogsgaard

        The stack overflow could be caused by recursive calling OnTimer(UINT nIDEvent). How does the call stack look after the exception? Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

        R Offline
        R Offline
        RobJones
        wrote on last edited by
        #3

        Sorry, I'm new to programming and I'm not sure what the call stack is.. is this maybe what your talking about: 139: void CAdd1Dlg::OnTimer(UINT nIDEvent) 140: { 00402750 push ebp 00402751 mov ebp,esp 00402753 push 0FFh 00402755 push offset __ehhandler$?OnTimer@CAdd1Dlg@@IAEXI@Z (00551555) 0040275A mov eax,fs:[00000000] 00402760 push eax 00402761 mov dword ptr fs:[0],esp 00402768 sub esp,0B78h -> 0040276E push ebx 0040276F push esi 00402770 push edi 00402771 push ecx 00402772 lea edi,[ebp-0B84h] 00402778 mov ecx,2DEh 0040277D mov eax,0CCCCCCCCh 00402782 rep stos dword ptr [edi] 00402784 pop ecx 00402785 mov dword ptr [ebp-10h],ecx 141: switch (nIDEvent) Sorry for my ignorance.. Thanks for your help! :) Rob

        K S 2 Replies Last reply
        0
        • R RobJones

          Sorry, I'm new to programming and I'm not sure what the call stack is.. is this maybe what your talking about: 139: void CAdd1Dlg::OnTimer(UINT nIDEvent) 140: { 00402750 push ebp 00402751 mov ebp,esp 00402753 push 0FFh 00402755 push offset __ehhandler$?OnTimer@CAdd1Dlg@@IAEXI@Z (00551555) 0040275A mov eax,fs:[00000000] 00402760 push eax 00402761 mov dword ptr fs:[0],esp 00402768 sub esp,0B78h -> 0040276E push ebx 0040276F push esi 00402770 push edi 00402771 push ecx 00402772 lea edi,[ebp-0B84h] 00402778 mov ecx,2DEh 0040277D mov eax,0CCCCCCCCh 00402782 rep stos dword ptr [edi] 00402784 pop ecx 00402785 mov dword ptr [ebp-10h],ecx 141: switch (nIDEvent) Sorry for my ignorance.. Thanks for your help! :) Rob

          K Offline
          K Offline
          k Andreas Hoheisel
          wrote on last edited by
          #4

          Try inline void CAdd1Dlg::OnTimer(UINT nIDEvent)

          R 1 Reply Last reply
          0
          • K k Andreas Hoheisel

            Try inline void CAdd1Dlg::OnTimer(UINT nIDEvent)

            R Offline
            R Offline
            RobJones
            wrote on last edited by
            #5

            Just tried it and I still get the same error.. :( Thanks for the help though, :) Rob

            1 Reply Last reply
            0
            • R RobJones

              Hello all, I have created a dialog type app.. I have a modeless dlg box that needs to run a timer, the reason it's Modeless is the timer needs to be active all the time even when the Dialog box it hidden (I'm checking if the timer is equal to a int every second, when they match I run a event).. I added the WM_TIMER function to this Modeless dialog.. When I fire the "OnTimer(UINT nIDEvent)" by doing a "SetTimer(IDC_S_TIMER1,1000,NULL);" from another control, I get the following error in debug mode: First-chance exception in Dialog.exe: 0xC00000FD: Stack Overflow. And it points to OnTimer(UINT nIDEvent) ->{ Any ideas why? :) Thanks, RobJones

              A Offline
              A Offline
              A R 0
              wrote on last edited by
              #6

              The Stack Overflow problem usually arises when you are (unaware) calling the same function several times as fast as you can, until the stack gets full X|. So, what are you doing inside of your OnTimer() function? Could it be possible that you are executing this same function (kind of recursive call, but without an exit condition)? On the other hand, where are you creating the timer? Could you please show us some of your code to handle the IDC_S_TIMER1 timer's id in your OnTimer() function?

              R 1 Reply Last reply
              0
              • A A R 0

                The Stack Overflow problem usually arises when you are (unaware) calling the same function several times as fast as you can, until the stack gets full X|. So, what are you doing inside of your OnTimer() function? Could it be possible that you are executing this same function (kind of recursive call, but without an exit condition)? On the other hand, where are you creating the timer? Could you please show us some of your code to handle the IDC_S_TIMER1 timer's id in your OnTimer() function?

                R Offline
                R Offline
                RobJones
                wrote on last edited by
                #7

                Sure... void CAdd1Dlg::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case IDC_S_TIMER1: //decrement the count iS --; //format and display the count m_ctlTime1.Display(iS,iM,iH,iD,(CString)m_strTime1="%D:%H:%M:%S"); break; } UpdateData(FALSE); CAdd1Dlg::OnTimer(nIDEvent); void OnTimerStart(); if(something.....) { } else { UpdateData(TRUE); //Start the timer iTa = iDa*24*60*60+iHa*60*60+iMa*60+iSa; iTPDT = iPDTD*24*60*60+iPDTH*60*60+iPDTM*60+iPDTS; iDiff = iTa-iTPDT; iS = iDiff; strTime.Format("%d",iS); SetTimer(IDC_S_TIMER1,1000,NULL); //Disable Start Button and enable stop m_bStopTime1.EnableWindow(TRUE); m_bStartTime1.EnableWindow(FALSE); m_bGrab1.EnableWindow(FALSE); GetDlgItem(IDC_E_MIN1)->EnableWindow(FALSE); GetDlgItem(IDC_E_SEC1)->EnableWindow(FALSE); GetDlgItem(IDC_E_QUANTITY)->EnableWindow(FALSE); GetDlgItem(IDC_E_MAXBID)->EnableWindow(FALSE); GetDlgItem(IDC_E_ITEM)->EnableWindow(FALSE); fileEditText.Remove(_T("Timestart.txt")); fileEditText.Remove(_T("TimeUrlstart.txt")); UpdateData(FALSE); } I can only find one section that I do a SetTimer()... The reason I use switch in nIDEvent is because I use to have 2 timere that i would switch between.. I only have 1 now.. I tried to remove the switch and I still get the same error.. Thanks for the help!!! Rob

                A 1 Reply Last reply
                0
                • R RobJones

                  Sure... void CAdd1Dlg::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case IDC_S_TIMER1: //decrement the count iS --; //format and display the count m_ctlTime1.Display(iS,iM,iH,iD,(CString)m_strTime1="%D:%H:%M:%S"); break; } UpdateData(FALSE); CAdd1Dlg::OnTimer(nIDEvent); void OnTimerStart(); if(something.....) { } else { UpdateData(TRUE); //Start the timer iTa = iDa*24*60*60+iHa*60*60+iMa*60+iSa; iTPDT = iPDTD*24*60*60+iPDTH*60*60+iPDTM*60+iPDTS; iDiff = iTa-iTPDT; iS = iDiff; strTime.Format("%d",iS); SetTimer(IDC_S_TIMER1,1000,NULL); //Disable Start Button and enable stop m_bStopTime1.EnableWindow(TRUE); m_bStartTime1.EnableWindow(FALSE); m_bGrab1.EnableWindow(FALSE); GetDlgItem(IDC_E_MIN1)->EnableWindow(FALSE); GetDlgItem(IDC_E_SEC1)->EnableWindow(FALSE); GetDlgItem(IDC_E_QUANTITY)->EnableWindow(FALSE); GetDlgItem(IDC_E_MAXBID)->EnableWindow(FALSE); GetDlgItem(IDC_E_ITEM)->EnableWindow(FALSE); fileEditText.Remove(_T("Timestart.txt")); fileEditText.Remove(_T("TimeUrlstart.txt")); UpdateData(FALSE); } I can only find one section that I do a SetTimer()... The reason I use switch in nIDEvent is because I use to have 2 timere that i would switch between.. I only have 1 now.. I tried to remove the switch and I still get the same error.. Thanks for the help!!! Rob

                  A Offline
                  A Offline
                  A R 0
                  wrote on last edited by
                  #8

                  Rob, It seems that you have some re-entrancy code and a very bad function call. You are calling your function (as I said in my previous message) inside of your function, creating a recursive call with no exit at all. Let me be more specific ... In your function OnTimer() you have a line at the end that says "CAdd1Dlg::OnTimer(nIDEvent)" and this is the horrible bug. Instead you have to call the base method, i.e. CDialog::OnTimer(nIDEvent). On the other hand, the timer has been set to signal every one second, and in the code where you are handling this event, there is no way to stop the messaging system sending the signal every one second, and here is where meanwhile you are decrementing your variable and formatting your display, another call has been made and so on. One good rule is if your timer's handler do a lot of work and the timer's period is short, you have to tell the messaging system "give me a break". So in your code, you can use something like: void CAdd1Dlg::OnTimer(UINT nIDEvent){ switch (nIDEvent){ case IDC_S_TIMER1: KillTimer(IDC_S_TIMER1); // Stop the timer //decrement the count iS --; //format and display the count m_ctlTime1.Display(iS,iM,iH,iD,(CString)m_strTime1="%D:%H:%M:%S"); UpdateData(FALSE); SetTimer(IDC_S_TIMER1, 1000, NULL); // Restart the timer break; } //UpdateData(FALSE); <=== Make this call before. //CAdd1Dlg::OnTimer(nIDEvent) <=== X| OOPS! This is the bad guy in your code CDialog::OnTimer(nIDEvent); // Use this instead. } I hope this helps Au revoir.

                  L S 2 Replies Last reply
                  0
                  • A A R 0

                    Rob, It seems that you have some re-entrancy code and a very bad function call. You are calling your function (as I said in my previous message) inside of your function, creating a recursive call with no exit at all. Let me be more specific ... In your function OnTimer() you have a line at the end that says "CAdd1Dlg::OnTimer(nIDEvent)" and this is the horrible bug. Instead you have to call the base method, i.e. CDialog::OnTimer(nIDEvent). On the other hand, the timer has been set to signal every one second, and in the code where you are handling this event, there is no way to stop the messaging system sending the signal every one second, and here is where meanwhile you are decrementing your variable and formatting your display, another call has been made and so on. One good rule is if your timer's handler do a lot of work and the timer's period is short, you have to tell the messaging system "give me a break". So in your code, you can use something like: void CAdd1Dlg::OnTimer(UINT nIDEvent){ switch (nIDEvent){ case IDC_S_TIMER1: KillTimer(IDC_S_TIMER1); // Stop the timer //decrement the count iS --; //format and display the count m_ctlTime1.Display(iS,iM,iH,iD,(CString)m_strTime1="%D:%H:%M:%S"); UpdateData(FALSE); SetTimer(IDC_S_TIMER1, 1000, NULL); // Restart the timer break; } //UpdateData(FALSE); <=== Make this call before. //CAdd1Dlg::OnTimer(nIDEvent) <=== X| OOPS! This is the bad guy in your code CDialog::OnTimer(nIDEvent); // Use this instead. } I hope this helps Au revoir.

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #9

                    THANK YOU VERY MUCH!!! Changing the CAdd1Dlg::OnTimer(nIDEvent) to CDialog::OnTimer(nIDEvent) fixed everything.. Thanks for taking the time to help! :-D Rob Jones

                    1 Reply Last reply
                    0
                    • A A R 0

                      Rob, It seems that you have some re-entrancy code and a very bad function call. You are calling your function (as I said in my previous message) inside of your function, creating a recursive call with no exit at all. Let me be more specific ... In your function OnTimer() you have a line at the end that says "CAdd1Dlg::OnTimer(nIDEvent)" and this is the horrible bug. Instead you have to call the base method, i.e. CDialog::OnTimer(nIDEvent). On the other hand, the timer has been set to signal every one second, and in the code where you are handling this event, there is no way to stop the messaging system sending the signal every one second, and here is where meanwhile you are decrementing your variable and formatting your display, another call has been made and so on. One good rule is if your timer's handler do a lot of work and the timer's period is short, you have to tell the messaging system "give me a break". So in your code, you can use something like: void CAdd1Dlg::OnTimer(UINT nIDEvent){ switch (nIDEvent){ case IDC_S_TIMER1: KillTimer(IDC_S_TIMER1); // Stop the timer //decrement the count iS --; //format and display the count m_ctlTime1.Display(iS,iM,iH,iD,(CString)m_strTime1="%D:%H:%M:%S"); UpdateData(FALSE); SetTimer(IDC_S_TIMER1, 1000, NULL); // Restart the timer break; } //UpdateData(FALSE); <=== Make this call before. //CAdd1Dlg::OnTimer(nIDEvent) <=== X| OOPS! This is the bad guy in your code CDialog::OnTimer(nIDEvent); // Use this instead. } I hope this helps Au revoir.

                      S Offline
                      S Offline
                      Steen Krogsgaard
                      wrote on last edited by
                      #10

                      Hi A.R. Your solution to Rob's recursive call problem is of course absolutely correct. However, I don't think Rob's got a re-entrance problem. >On the other hand, the timer has been set to signal every one second, and in the code where you are handling this event, there is no way to stop the messaging system sending the signal every one second, and here is where meanwhile you are decrementing your variable and formatting your display, another call has been made and so on. Rob is handling the WM_TIMER message, and while the program is in OnTimer it will not get new messages from the message queue and hence OnTimer will not be called again. Only when Rob returns from OnTimer will a new WM_TIMER message be dispatched. So while a steady stream of WM_TIMER messages will certainly make the application seem unresponsive, it will not lead to any concurrency issues. Furthermore, WM_TIMER messages are handled in a similar manner to WM_PAINT - they are low-priority and will only be handled if the message queue is empty, and multiple WM_TIMER messages in the queue will be merged into one message. And there is no way to find out just how may WM_TIMER messages got zapped. That's why you cannot use timers to make a good clock - you'll have to read the system time inside OnTimer, and cannot rely on exactly 1 second between WM_TIMER messages (not even on average over a period of time). And don't take my word for it - it's all described in Petzold chapter 7. >One good rule is if your timer's handler do a lot of work and the timer's period is short, you have to tell the messaging system "give me a break". This is actually very good advice, but only for responsivity-reasons, not for concurrency. Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

                      1 Reply Last reply
                      0
                      • R RobJones

                        Sorry, I'm new to programming and I'm not sure what the call stack is.. is this maybe what your talking about: 139: void CAdd1Dlg::OnTimer(UINT nIDEvent) 140: { 00402750 push ebp 00402751 mov ebp,esp 00402753 push 0FFh 00402755 push offset __ehhandler$?OnTimer@CAdd1Dlg@@IAEXI@Z (00551555) 0040275A mov eax,fs:[00000000] 00402760 push eax 00402761 mov dword ptr fs:[0],esp 00402768 sub esp,0B78h -> 0040276E push ebx 0040276F push esi 00402770 push edi 00402771 push ecx 00402772 lea edi,[ebp-0B84h] 00402778 mov ecx,2DEh 0040277D mov eax,0CCCCCCCCh 00402782 rep stos dword ptr [edi] 00402784 pop ecx 00402785 mov dword ptr [ebp-10h],ecx 141: switch (nIDEvent) Sorry for my ignorance.. Thanks for your help! :) Rob

                        S Offline
                        S Offline
                        Steen Krogsgaard
                        wrote on last edited by
                        #11

                        Hi Rob, glad to be of assistance. What you've posted is the disassembly - 10-15 years ago people would actually program writing this mumbo-jumbo! ;) Assuming you're using MS VC++, you can see the call stack _when you're debugging_ by pressing alt+7 (or choosing View->Debug windows->Call Stack. You can also see it in the variables window by expanding the combo box at the top of this window, the one labeled "context". The call stack is a list of all the calls that led to the point in the program where you are right now. This is how the call stack looked i a test program using OnTimer: CTest10View::OnTimer(unsigned int 1) line 139 CWnd::OnWndMsg(unsigned int 275, unsigned int 1, long 0, long * 0x0012fd10) line 1829 CWnd::WindowProc(unsigned int 275, unsigned int 1, long 0) line 1585 + 30 bytes AfxCallWndProc(CWnd * 0x00422cf0 {CTest10View hWnd=0x0006031a}, HWND__ * 0x0006031a, unsigned int 275, unsigned int 1, long 0) line 215 + 26 bytes AfxWndProc(HWND__ * 0x0006031a, unsigned int 275, unsigned int 1, long 0) line 368 AfxWndProcBase(HWND__ * 0x0006031a, unsigned int 275, unsigned int 1, long 0) line 220 + 21 bytes USER32! 77e13eb0() USER32! 77e1401a() USER32! 77e192da() CWinThread::Run() line 480 + 11 bytes CWinApp::Run() line 400 AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001325f8, int 1) line 49 + 11 bytes WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001325f8, int 1) line 30 WinMainCRTStartup() line 330 + 54 bytes KERNEL32! 77e87903() Reading from bottom up you can find the call to WinMain which call AfxWinMain, which called CWinApp::Run() which callled CWinThread::Run() which called GetMessage and DispatchMessage (the USER32! things). Then you can see the trace through the MFC windows procedures (WinProc, AfxCallWndProc, CWnd::WindowProc) and the routing through the message map (CWnd::OnWndMsg and finally CTest10View::OnTimer). Cheers Steen. "To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups