-
September 29th, 2010, 10:22 AM
#1
[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?
-
September 29th, 2010, 10:28 AM
#2
Re: Keeping GUI responsive
Code:
/* Handle window events */
void DoEvents ()
{
MSG stMsg;
while (::PeekMessage (&stMsg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage (&stMsg);
::DispatchMessage (&stMsg);
}
}
-
September 29th, 2010, 10:35 AM
#3
Re: Keeping GUI responsive
That's exactly what I was looking for, thanks!
-
October 4th, 2010, 09:12 AM
#4
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;
}
-
September 29th, 2010, 02:28 PM
#5
Re: [RESOLVED] Keeping GUI responsive
Originally Posted by Ankheg
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
-
September 29th, 2010, 03:24 PM
#6
Re: [RESOLVED] Keeping GUI responsive
Originally Posted by Arjay
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?
-
September 29th, 2010, 03:42 PM
#7
Re: [RESOLVED] Keeping GUI responsive
Originally Posted by Ankheg
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.
-
September 29th, 2010, 03:45 PM
#8
Re: [RESOLVED] Keeping GUI responsive
Originally Posted by Ankheg
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.
-
September 30th, 2010, 07:13 AM
#9
Re: [RESOLVED] Keeping GUI responsive
Originally Posted by Arjay
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.
-
September 30th, 2010, 08:43 AM
#10
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.
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|