CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Aug 2010
    Posts
    47

    [RESOLVED] Keeping GUI responsive

    Hi there!

    So I have a fairly long/intensive loop in one of my functions that when it runs the GUI stops responding to mouse events (and other events, I'm sure). It seems like there should be two solutions, one is to give the GUI a chance every once in a while to refresh and the other would be to put the processing into it's own thread.

    I've been looking around for a way to do the first, and haven't run across anything yet. This particular function isn't something that the typical user will use, it's more of a testing function, so I'm not worried about it being extremely user friendly... I would like to be able to reposition or minimize the window while it works though. Choppy response is fine.

    Could someone point me to a function that would give the GUI a chance to process messages?

    I'm sure putting it in it's own thread is the "better" solution, but I haven't touched threads yet on C++ and I'm hoping not to open that can of worms right now, but failing the above can you point me towards a simple example of how to spawn a thread?

  2. #2
    Join Date
    Sep 2004
    Location
    Holland (land of the dope)
    Posts
    4,123

    Re: Keeping GUI responsive

    Code:
    /* Handle window events */
    void DoEvents ()
    {
    	MSG	stMsg;
    
    	while (::PeekMessage (&stMsg, NULL, 0, 0, PM_REMOVE)) 
    	{
    		::TranslateMessage (&stMsg);
    		::DispatchMessage (&stMsg);
    	}
    }

  3. #3
    Join Date
    Aug 2010
    Posts
    47

    Re: Keeping GUI responsive

    That's exactly what I was looking for, thanks!

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: [RESOLVED] Keeping GUI responsive

    Quote Originally Posted by Ankheg View Post
    I'm sure putting it in it's own thread is the "better" solution, but I haven't touched threads yet on C++ and I'm hoping not to open that can of worms right now, but failing the above can you point me towards a simple example of how to spawn a thread?
    Pumping messages are the quick and dirty way, but as you need more features, things can become unwieldy fast.

    Threading isn't too hard. Take a look at a couple of my example articles listed in my signature line.


    __________________________________________________________
    Arjay

    See my latest series on using WCF to communicate between a Windows Service and WPF task bar application.
    Tray Notify - Part I Tray Notify - Part II

    Need a little help with Win32 thread synchronization? Check out the following CG articles and posts:
    Sharing a thread safe std::queue between threads w/progress bar updating
    Simple Thread: Part I Simple Thread: Part II
    Win32 Thread Synchronization, Part I: Overview Win32 Thread Synchronization, Part 2: Helper Classes

    www.iridyn.com


  5. #5
    Join Date
    Aug 2010
    Posts
    47

    Re: [RESOLVED] Keeping GUI responsive

    Quote Originally Posted by Arjay View Post
    Pumping messages are the quick and dirty way, but as you need more features, things can become unwieldy fast.

    Threading isn't too hard. Take a look at a couple of my example articles listed in my signature line.
    In this case it seems to work well. If I start needing to do more things later, I'll probably go take a look, but for now I'm trying to stay focused on getting things done.

    It did crash on me when I closed the window without letting it run it's course, but I fixed that by having the destructor set a flag to let the function code know that it should exit. Then all I needed to do was check that flag and release some memory.

    It seems a little strange to me that my function can still run, and access member variables after the destructor for the object the function is in has been called, but *shrug*. Think that'll have some sort of strange effects that will come back to haunt me later?

  6. #6
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: [RESOLVED] Keeping GUI responsive

    Quote Originally Posted by Ankheg View Post
    It seems a little strange to me that my function can still run, and access member variables after the destructor for the object the function is in has been called, but *shrug*. Think that'll have some sort of strange effects that will come back to haunt me later?
    Probably. Such behavior is undefined.

  7. #7
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: [RESOLVED] Keeping GUI responsive

    Quote Originally Posted by Ankheg View Post
    It seems a little strange to me that my function can still run, and access member variables after the destructor for the object the function is in has been called, but *shrug*. Think that'll have some sort of strange effects that will come back to haunt me later?
    Usually what happens is the window objects go away before and classes are destructed (if you are using a framework like MFC). Since class methods are still active even after the windows has closed - the problem is when these methods access some window control that no longer exists.

  8. #8
    Join Date
    Aug 2010
    Posts
    47

    Re: [RESOLVED] Keeping GUI responsive

    Quote Originally Posted by Arjay View Post
    Usually what happens is the window objects go away before and classes are destructed (if you are using a framework like MFC). Since class methods are still active even after the windows has closed - the problem is when these methods access some window control that no longer exists.
    Yeah, that's pretty much what happened. During my function I would update the window regularly to keep me informed as to what was happening. If I closed the window, it would continue to run until it hit the window update, and then crash.

    So basically right after I did the message processing, I now have the function check the "am I exiting" variable that gets set in the destructor, do some cleanup, and exit the function. Unless someone tells me that this is a terrible abuse of the language and that it will make my program explode at some point, I'll probably leave it as it is.

  9. #9
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: [RESOLVED] Keeping GUI responsive

    It's fine so long as the destructor doesn't finish running prior to that check. For instance, if you're doing the message processing in a different thread and you had pseudocode like this it would be fine:

    Code:
    Object::~Object()
    {
        LOCK mutex;
        SET finished flag;
        UNLOCK mutex;
        JOIN event thread;
    }
    
    void Object::eventLoop()
    {
        LOCK mutex;
        while (!finished)
        {
            UNLOCK mutex;
            PROCESS EVENTS
            LOCK mutex;
        }
        UNLOCK mutex;
    }
    That's fine. But once the destructor returns, it is absolutely unsafe to try accessing any members of the object.

  10. #10
    Join Date
    Aug 2010
    Posts
    47

    Re: Keeping GUI responsive

    I just wanted to update this thread in case of people running across the thread in search engines and trying out the solution I used. I did run across another bug which wasn't a big deal in my case but others probably would have found it a big deal. Basically the app would hang if you closed it. This was because I wasn't reposting the WM_QUIT message and so it wasn't being processed properly outside of my code.

    Here's a quick rundown of what I'm currently using. In the destructor I set a member variable flag m_exit to TRUE. Then in my function I regularly call something like this:

    Code:
    MSG	stMsg;
    
    while (::PeekMessage (&stMsg, NULL, 0, 0, PM_REMOVE)) 
    {
    	if (stMsg.message == WM_QUIT)
    	{
    		// memory deallocation/cleanup here
    		PostQuitMessage(0);
    		return;
    	}
    	::TranslateMessage (&stMsg);
    	::DispatchMessage (&stMsg);
    }
    if (m_exit)
    {
    	// memory deallocation/cleanup here
    	return;
    }

Tags for this Thread

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