Windows Application User-Interface Freezes?
Question:
I recently purchased the Chilkat HTTP component and am using it with a Visual FoxPro application. However, each time I run it the form freezes and I get the Not Responding message in the title bar. I have an animated GIF that I am using as a quasi-progress meter but that freezes as well. As soon as the HTTP Download finished, the form gets the focus back and the download is successful.
I need the animated GIF to keep working and to avoid the freeze and Not Responding message. Happens every time. Plus the mouse cursor pointer disappears from the VFP form.
Answer:
To answer this question, I must first describe the basic architecture of all interactive Windows-based applications w/ user-interfaces. This applies to all programming languages: FoxPro, VB6, MFC (C++), C#, VB.NET, etc.
Microsoft Windows programs are event-based. They act upon messages that the operating system posts to the main application thread. These messages are received from the message queue by the application by repeatedly calling the GetMessage (or PeekMessage) function in a section of code called the “event loop.” (See this Wikipedia article: Message Loop in Microsoft Windows)
In higher-level programming languages such as FoxPro, VB6, etc., the actual code for the app’s message loop is hidden from you. The application programmer interactively designs a user-interface and provides code (handlers) for user-interface events. For example, when “Button A” is pressed, call this subroutine (or function). Typically, the code in your button handler finishes quickly and returns control back to the caller. It happens so fast that you never notice that technically the user-interface was “frozen” for the short amount of time spent in your button-handler code.
It becomes apparent that user-interface events are not being handled when your application code takes longer to complete before returning control back to the app’s main event loop (i.e. before returning control to the FoxPro, VB6, C#, etc. runtime). It may also help to think of it this way: Since the application is single-threaded, it can only be doing one thing at a time. While the application thread is executing the application code, it can’t possibly be doing something else, such as executing code to update the user-interface.
The solution is that within your application code you must periodically handle any accumulated user-interface events. In Visual Basic 6.0, C#, and VB.NET, this is accomplished by calling the DoEvents function:
(from the Microsoft online documentation for Application.DoEvents)
“When you run a Windows Form, it creates the new form, which then waits for events to handle. Each time the form handles an event, it processes all the code associated with that event. All other events wait in the queue. While your code handles the event, your application does not respond. For example, the window does not repaint if another window is dragged on top.
If you call DoEvents in your code, your application can handle the other events. For example, if you have a form that adds data to a ListBox and add DoEvents to your code, your form repaints when another window is dragged over it. If you remove DoEvents from your code, your form will not repaint until the click event handler of the button is finished executing…”
In Visual FoxPro, it is the DOEVENTS command.
Since the bulk of the time spent within your application code may be within a Chilkat function call (especially if it involves communications over the Internet), then you must tell the Chilkat component to make periodic callbacks to your application code, so that your application can then call DoEvents. The standard way of doing this w/ Chilkat is via the AbortCheck event. The HeartbeatMs property controls the frequency of AbortCheck event callbacks. The default value is 0, which indicates no AbortCheck events. Set it to a value such as 100 for event callbacks every 1/10 of a second.
For more information: ActiveX Events in FoxPro
For more information: AbortCheck in C# and VB.NET