Re: Win32Lib doEvents()
- Posted by Matt Lewis <matthewwalkerlewis at gmail.com> Jul 08, 2005
- 582 views
Larry Miller wrote: > > I have found doEvents to be very useful but there is a potential problem in > it's use. > The problem occurs when PeekMessage in doEvents receives a WM_QUIT message. > GetMessage > in the event loop tests for this and terminates the loop and the application. > But in > doEvents there is no such test and this will cause a serious problem. > > The following code illustrates the problem. Yes, it is contrived and not the > way an > application would normally do things, but it does illustrate the basic > problem. > <snip> > If you click on the windows close button the window will close, but Task > Manager shows > that the process is still very much alive - and with very high CPU usage. > > The problem does not appear to be unique to Win32Lib. I have examined the code > of ARWEN > and it's doEvents() function appears to work in a similar maner, and subject > to the > same problem. (I have not actually confirmed the problem in ARWEN). > > In my case I have replaced doEvents() with a procedure that does test for > WM_QUIT and > then shuts down the application. But I am not certain that this is the best > solution > to the problem. > > In any case this issue should be resolved in Win32Lib. > Yes, this is definitely a problem. It's interesting that this has never been caught before. The solution is probably to catch the WM_QUIT, but not to act on it until getting back to event_loop. Here are some changes you can make to solve this problem (though of course it won't get you out of your infinite loop, which win32lib can't help. First, here's a modified test app:
include win32lib.ew without warning atom Win procedure handler(integer id,atom event,sequence param) atom t if event=w32HActivate then t = time() while time() < t + 5 do doEvents(0) end while end if end procedure Win=create(Window,"Test",0,100,100,600,400,0) setHandler(Win,w32HActivate,routine_id("handler")) WinMain(Win,Normal)
Now, here is how you need to change win32lib:
-- begin mwl 7/8/05 (right above eventLoop()): integer vWmQuit vWmQuit = 0 -- end mwl 7/8/05 -- then, inside eventLoop(): -- message loop while ActiveEL[el] = 0 and vWinMainState = kStarted -- begin mwl 7/8/05 and vWmQuit = 0 do -- end mwl 7/8/05 -- and finally, inside of doEvents(): if w32Func( xPeekMessage, { msg, hWnd, 0, 0, PM_REMOVE } ) then -- begin mwl 7/8/05 if peek4u(msg+4) = WM_QUIT then vWmQuit = 1 end if -- end mwl 7/8/05
Matt Lewis