CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Nov 2012
    Location
    Edinburgh
    Posts
    20

    SetTimer/OnTimer causes file menu to flicker.

    I have a (large) application that works perfectly under XP. When I run it under Windows 7 the "File Edit View..." menu in my application flickers when everything is otherwise idle.

    I have traced this down to SetTimer and its associated OnTimer function. OnTimer usually does nothing, so I have commented out everything leaving this:
    Code:
    void MyView::OnTimer(UINT nIDEvent) { }
    I have also changed the SetTimer call to give one tick every five seconds.

    I now see the same behaviour: the File menu is very briefly greyed-out every five seconds, leading to the flicker. Nothing else in the window is exhibiting this flicker.

    So, I have a call to a null function every five seconds that manages to affect a menu.

    Any ideas as to what may be causing this?

  2. #2
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SetTimer/OnTimer causes file menu to flicker.

    What happens if you call the base class OnTimer?
    Code:
    void MyView::OnTimer(UINT nIDEvent) { CView::OnTimer(nIDEvent) ;}
    BTW, do you use some OnUpdate... for menu items"
    Or do you somehow handle WM_INITMENUPOPUP message?
    Victor Nijegorodov

  3. #3
    Join Date
    Nov 2012
    Location
    Edinburgh
    Posts
    20

    Re: SetTimer/OnTimer causes file menu to flicker.

    The call to the base class was in the original code that was commented out. Putting it back in makes no difference.

    WM_INITMENUPOPUP messages are not mentioned in the code.

    OnUpdate is handled for all of the menu items. Interestingly, commenting out the code for the File update stops the flicker.
    It seems this is getting called each time the timer ticks, but why?

  4. #4
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SetTimer/OnTimer causes file menu to flicker.

    Quote Originally Posted by Peter Robertson View Post
    ... Interestingly, commenting out the code for the File update stops the flicker.
    It seems this is getting called each time the timer ticks, but why?
    How did you implement it?
    Victor Nijegorodov

  5. #5
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: SetTimer/OnTimer causes file menu to flicker.

    Quote Originally Posted by Peter Robertson View Post
    OnUpdate is handled for all of the menu items. Interestingly, commenting out the code for the File update stops the flicker.
    It seems this is getting called each time the timer ticks, but why?
    IIRC, the OnUpdate functions are called each time the message loop is idle (i.e. all messages have been processed). It could be that the code in your OnUpdate functions is too slow. Maybe you could refactor the code such that you store the state that you need in these functions and update the state whenever it changes.
    E.g. in your main frame class you have a bool m_IsCalculating and you have a menu item called 'Calculate' that you update as
    Code:
    void CMainFrame::OnUpdateCalculate(CCmdUI* pCmdUI)
    {
        pCmdUI->Enable(!m_IsCalculating);
    }
    Whenever you start a calculation (in a worker thread, of course) you set the bool to true and when the calculation is complete you set it back to false.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  6. #6
    Join Date
    Nov 2012
    Location
    Edinburgh
    Posts
    20

    Re: SetTimer/OnTimer causes file menu to flicker.

    That's essentially what I have. Unfortunately the simple call to Enable resulted in the menu never being re-enabled,
    so the code grew other stuff and that is probably causing the problem. I can inhibit it in most cases, so that's what I shall do.

    So whenever the message loop empties, all sorts of stuff is called 'just in case'?
    Does anyone else get the feeling that all of this is very ad hoc and not well designed?

  7. #7
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SetTimer/OnTimer causes file menu to flicker.

    Quote Originally Posted by Peter Robertson View Post
    That's essentially what I have.
    *What* exactly do you have? Lengthy computations within the OnUpdate... hadler? Or what?

    Quote Originally Posted by Peter Robertson View Post
    Unfortunately the simple call to Enable resulted in the menu never being re-enabled
    Why?
    Victor Nijegorodov

  8. #8
    Join Date
    Nov 2012
    Location
    Edinburgh
    Posts
    20

    Re: SetTimer/OnTimer causes file menu to flicker.

    Code:
    void MyDoc::OnUpdateFileApplication(CCmdUI *pCmdUI) {
       pCmdUI->Enable(Running==false);
       UINT Enable = (Running==false) ? MF_BYPOSITION | MF_ENABLED
                                      : MF_BYPOSITION | MF_GRAYED;
       CMenu *Menu = AfxGetMainWnd()->GetMenu();
       Menu->EnableMenuItem(0, Enable);
       if (Running != LastRunning) {
          LastRunning = Running;
          AfxGetMainWnd()->DrawMenuBar();
       }
    }
    The flickering comes when the LastRunning tests are removed, clearly caused by DrawMenuBar.
    Removing the call on DrawMenuBar altogether results in the File menu item remaining greyed-out even when Running becomes false until the cursor moves over it.

  9. #9
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SetTimer/OnTimer causes file menu to flicker.

    Why do you update the item in the menu bar (and redraw the whole bar as well) from within the message handler for some submenu item?
    It will only be called in response on the user action like clinking on the menu item in the menu bar!
    Perhaps, you'd implement something like what was suggested in this thread?
    Victor Nijegorodov

  10. #10
    Join Date
    Nov 2012
    Location
    Edinburgh
    Posts
    20

    Re: SetTimer/OnTimer causes file menu to flicker.

    The thread you reference seems to be suggesting what I am already doing.

    Unless I've missed something, the handler is not only called when the user clicks a menu item; as discussed earlier it is called when the message loop becomes empty.
    I'm not sure where submenu items appeared from; the item in question is a handler for 'File' in the main menu.

    The event that causes the menu item to be enabled is not a user action but something external.

    The code in its current form is the result of a long and tedious process to get something to work. I would much prefer a simpler solution, but this is the only thing that I have found to give acceptable results.

  11. #11
    VictorN's Avatar
    VictorN is online now Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: SetTimer/OnTimer causes file menu to flicker.

    No, OnUpdate... message handlers for menu items are called from within the CFrameWnd::OnInitMenuPopup message handler (if OnUpdate... for the the submenu items exist). See http://www.microsoft.com/msj/0299/c/c0299.aspx
    For ControlBars (toolbar, statusbar, ...) OnUpdate... handler are called from OnIdle.
    Victor Nijegorodov

  12. #12
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: SetTimer/OnTimer causes file menu to flicker.

    Quote Originally Posted by Peter Robertson View Post
    So whenever the message loop empties, all sorts of stuff is called 'just in case'?
    Does anyone else get the feeling that all of this is very ad hoc and not well designed?
    Not 'just in case', it is called when necessary. I was inaccurate about the call to OnUpdate....
    As Victor said, OnUpdate... for a submenu item is only called when that menu is opened (and, thus, the item becomes visible). See this for more info: http://social.msdn.microsoft.com/For...-5795ebdaf7d8/
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  13. #13
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: SetTimer/OnTimer causes file menu to flicker.

    Quote Originally Posted by Peter Robertson View Post
    Code:
    void MyDoc::OnUpdateFileApplication(CCmdUI *pCmdUI) {
       pCmdUI->Enable(Running==false);
       UINT Enable = (Running==false) ? MF_BYPOSITION | MF_ENABLED
                                      : MF_BYPOSITION | MF_GRAYED;
       CMenu *Menu = AfxGetMainWnd()->GetMenu();
       Menu->EnableMenuItem(0, Enable);
       if (Running != LastRunning) {
          LastRunning = Running;
          AfxGetMainWnd()->DrawMenuBar();
       }
    }
    The flickering comes when the LastRunning tests are removed, clearly caused by DrawMenuBar.
    Removing the call on DrawMenuBar altogether results in the File menu item remaining greyed-out even when Running becomes false until the cursor moves over it.
    Ok, so this is the handler function for the (top-level) File menu item, right? Then all you should need is the call to pCmdUI->Enable(...).
    Whenever you change Running, you may need to call DrawMenuBar to make 100% sure that the menu will be updated. It will also be updated after the user moves the mouse and OnIdle is called again.
    You are changing Running only from the main thread, right? Not from a worker thread?

    Taking a step back, my main question now is: why do you want to disable the File menu? As a user I can understand not being able to open, save or close a file while the application is busy, but why should I not be allowed to open the File menu?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured