Why my form go to the top of my screen when my UI freeze? - forms

I have a little issue with a form in a delphy XE2 application:
It's an old issue on this application and i have begin to work on it just since a little time.
When the user choose to launch the process with a button's event, my application launch a connexion with an OPCServer , an SQLServer and construct the form for a good following of data take on the tow servers.
The construction of my form involves a blockage of the interface (for approximately 15 sec) because of lot's of data which are necessary for make it.
When it freeze, if the user want drag the form, she go far away, and usually with the TMainMenu which go out of the screen. After that, it's impossible to use the application because we can't drag and we need to close and re-open.
In the old version, the form be already construct before the connexion. So the modification for a dynamic form isn't in link with this issue.
Life of my event :
-Open connexion with OPC Server
-Open SQL Connexion
-Send SQL Command Text
-FieldByName('') for update my UI (Button.Caption// TPage.TStaticText.Caption // TPage.Label1.Caption)
-FieldByName('') for update an array of record
-Close SQL Connexion
-Open SQL Connexion
-Send SQL CommandText
-FieldByName('') for update an other array of record
-Panel.Visible(false)
-TPage.Panel.Show;
-TPage.Panel.BringToFront;
So I haven't MainForm modification can change its position.
I'm a young developer, so I don't know why it moving and what I can make for repair that...
If you want a part of code, ask me what and i edit this, it's very long and i don't want spam answer.
Thank's for read.

The core of your problem is that you have a lengthy process (form construction) which completely blocks the main thread so your application isn't able to process normal Windows messages at the same time. That is why when you move your application it doesn't properly update its interface.
Now based on your description you already have this form construction process split into multiple steps so you could call Application.ProcessMessages between them.
This will force your application to update its UI part.
But beware calling Application.ProcessMessages often could hurt your application performance quite a bit. Why? It is usually a lengthy process because it forces your application to process all the messages that are in its queue.
Normally not all of these messages get processed as soon as they arrive. Windows groups them in the message queue by their priority list, making sure that high priority messages like WM_PAINT are processed as soon as possible while some other low priority messages like demand for application to respond to OS so that OS can see if the application is still working are mostly processed when application is idle or when they are in queue for certain amount of time.
So that is why Application.ProcessMessages can be so slow as it forces your application to process all messages regardless of their priority.
Also bear in mind that using Application.ProcessMessages can in certain scenarios actually become a bit dangerous.
Let me give you an example:
Lets say that clicking on a button starts a lengthy job which can take some time to finish. Now in order to allow your form to be updated you call Application.ProcessMessages in certain intervals. So far it is all good. But what happens if user clicks on that button again?
Since you are calling Application.ProcessMessages which forces your application to process all the messages and since clicking on button creates a MouseClick message which then fires buttons OnClick event which then executes the OnClick method that has been assigned to buttons OnClick event in the end this will cause the same method that was executed on first button click to be executed again.
So now you have this method partially done from first button click and same method executing again for second mouse click. Now the method that was executed from the second click will finish first and then the method that was started from first button click but was interrupted with Application.ProcessMessages handling the second button click will continue its execution to the end.
This all can lead to strange bugs which are hard to track, because you as a programmer normally don't predict that your end user might have clicked the button twice.
So to avoid this I strongly recommend you implement some safeguard mechanisms to prevent such scenarios by temporarily disabling a button for instance.
But the best solution is always to show your user that your application is working which in most cases will dissuade them from clicking the button again, but unfortunately not always.
You should also take a good care when dynamically constructing a form to enable the controls only after all of the controls have been successfully constructed. Failing to do so the user might click on one of your controls and that control could attempt to access some other control which hasn't yet been created at the time. The result hard to track bug which causes Access Violation.
You might also consider showing a splash screen at start instead of half built form. Why?
For once it is much nicer to see and it tells your users to wait a bit. And for second having main form hidden until it is fully created makes sure that user won't be doing any clicks on it prematurely.

Related

Eclipse Scout Neon Message box triggered on server side

I am wondering if there is a way to trigger message box on server side.
My case is that I have some logic on server side of the scout application. In the middle of the process some decision need to be made. It this case I would like to trigger message box with YES, NO, CANCEL options.
The way my logic works it really hard to split it into two functions and call one first, ask question and call another with on answer. So this is out of the way for me.
If it is not possible to triggered message box on scout service, is there a way to "mimic" it. So call service method, in the middle pause it, go to client side, present messsage box, return to same service method and continue it.
Why do I need this:
I have dependencies graph (between fields) implemented on scout server side.
After one field has been changed, the whole dependencies graph will be resolved.
One node of the graph has some logic that need user interaction. Problem is that I don't know if this method will be called (dependent on a graph), and if after this method other nods will be called.
You have asked a very similar question few months ago:
Scout Eclipse present optional message on server side
MessageBox is a client concept (package is: org.eclipse.scout.rt.client.ui.messagebox).
You need to transfert the data you need from the server to the client and intercept this information client-side to display the message box you want.
As Jmini already said, MessageBox is a client concept. What you can do is sending back a status (from server to client), checking it on client side and show an appropriate message (box). But then you interrupt your service method and cannot go on where it stopped (alternatively you can throw a VetoException, but this interrupts your service method aswell, so same problem). In my opinion, it is also not a good design to 'request' a user interaction from server side, because in this case, the server side has to wait for the user to respond.
I suggest, if possible, to split your logic into different parts. At first, you execute the first part until you reach the point where you need the user interaction. Then you could save the current state of execution, return to client and show the message. After the user has responded, you should start the 'second' execution, depending on the user's input. This second execution should be started by calling another (new) service, which at first should load or restore the state of the execution saved before requesting the user input.

How to stop runaway processes

So I'm working on this application that requests and retrieves webservice content for iPhone. The problem I am running into is this: When I initially request data, it is spawned off as an independent thread so that the application does not become unresponsive due to the network being slow. What this means is that if the user navigates away from the current page before this data finishes downloading, unexpected things can happen.
I have managed to narrow down the problem cases to one relatively simple one: I have some nested tables, so if a user goes down into the "Messages" table, which can sometimes take a little while to download, then back out immediately, and select a different set of messages to view, the previous set of messages ends up loading, because it was still in the queue.
Here are things I have tried:
1) I tried cancelling the operations, but this is futile, because since I only allow one operation in the queue at the time, it triggers immediately
2) I tried validating that the recipient of the data is the same, but this doesn't work because the actual table object is the between the two selections, it just needs a different data set.
Anyone have any general programming suggestions on how to solve this tricky threading problem?
On an iPhone specific note: if I could just stop the user from being able to back out of the messages table, I wouldn't have this problem, because they would basically be locked into that view until the data has finished loading.
Thanks!
This post has some design advice relating to iOS networking and threading. The basic gist of it is "Don't use explicit threading", and I couldn't agree more. NSURLConnection has great built-in functionality for asynchronously loading data from a URL while managing all of the threading for you. They can also be cancelled easily at will.
If you were to use the NSURLConnection paradigm, you can simply cancel any pending request when you back out of the requesting view controller.

iPhone: How to Implement a HTML Welcome Panel

I'd like to integrate something like a welcome panel (welcome screen) into our iPhone application to inform our users about updates and new offers when they launch the application. I have the following thoughts and doubts:
No user input required
Shows generic HTML without any action from the user point of view, the thing closes after 2 or 3 secs and has a close button if you want to close it manually. This is for advertising and tips.
This should be very simple to implement
User input required
Shows generic HTML with an action required from the user point of view, for example a survey. The user should be able to skip it
same as above, but is it possible that the user submits something on a HTML page and that causes also something to happen within the iPhone app (maybe via Java Script)? For example the user submits a survey on the HTML page and then app closes the current screen and continues to the next screen (i.e. the real application)?
Is it also possible to receive parameters (e.g. an ID) via a HTML website? e.g. if the user receives an offer on the HTML welcome panel, then he clicks on it and it takes him directly to a screen in the iPhone app with content loaded from a server (via JSON) depening on the offer id retrieved through the HTML page.
We prefer implementing it via HTML, because it gives us more flexibility. But I'm also open to hear other suggestions.
Thanks
Rengers answer is the correct one to accomplish what you want. However, the real correct answer is "Don't do that in the first place."
From a design perspective, a "Welcome Panel" or any kind of startup/splash-screen is a bad idea and the Apple Documentation tells you explicitly not to use them. Even for games, they're a bad idea that should be avoided if possible.
It's not a "Welcome Panel" it's a "wade-through-all-our-marketing-crap-before-you-can-actually-use-our-app" panel.
Mobile apps aren't like apps for regular platforms. Non-mobile hardware is faster so the obtrusive startup screens load faster and can be dismissed faster. Non-mobile apps tend to accomplish many task and people use them sitting down for prolonged periods. Users will tolerate a few seconds wasted clicking through startup screens so they can get into an app they will use for many minutes or even hours.
By contrast, mobile apps are often used by people on the go and in a hurry. The apps are small and ideally perform a single task. As quickly as possible, people need to be able to get into the app, perform what ever task the app accomplishes and then get back out again. If you're only using an app each time for 30 seconds or so, having to spend 5 seconds each time wading through startup screens is massively annoying.
Mobil hardware is slower and operations can take longer. Depending on its complexity and resources an app can take as much as 10 seconds to launch. In your case you want to add to a startup screen that has to load, connect to a url, display and then have the user perform an operation. That will take another 5-10 seconds minimum. So you're looking at users having to spend 20 seconds or more just getting into your app.
That doesn't sound like much but try mocking up your app and then using it on the go i.e. while walking, waiting for an elevator, going up the stairs, waiting for a red light etc. Test it in social situations. In the middle of conversation say, "Let me check on that" then take out the iPhone launch your app and try to get some information from it. 20 seconds becomes a very long time in all these circumstances.
Even shorter launch times are very annoying if you have to take some action every single time you open the app just to get to the functional part of the app. It's arguably even worse to spring a startup screen on them intermittently so they never know when they open your app how long it will take to get in it. User surprise is not good design.
Instead of forcing users to do something, you should embed advertisements and update notices unobtrusively in the app itself so that people can see them while they are using the app. In the case of advertising, this has the added advantage of putting the adds in view the entire time the user is looking at the app.
I don't know how many times some idiot from marketing has come in and started a feature request with, "We need to force the user to..." The only response to those types of request is to set the marketing weeny on fire. Do that several times and they'll stop trying to systematically alienate your customers.
UIWebViewDelegate has a method that allows you to respond to interaction in a HTML page:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
Using this, you can catch any links clicked and respond to them in your application by presenting a different view.
Recieving parameters like an id can be done in a few different ways.
1) You can parse the HTML and determine it from the source.
2) You can have a javascript function in the HTML that returns the id. Call it by using
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
3) You can also use the delegate method I mentioned.
If you make a link like this: get offer you can catch it in the delegate and retrieve the id from the NSURLRequest.
I hope this will point you in the right direction.
If you do need some kind of startup screen a good option is to use the default.png. The app loads and displays that image before it does anything else.
It's usually used to display the illusion of the user interface before the UI loads completely. However, you could use it to display startup information. Since it displays almost instantly (within 1 sec) it does give your user something to look at while the app loads. In the case of a mock interface, it lets the user see the location of the interface elements and begin moving to activate them before the elements finish loading.
The catch is that the image disappears as soon as the first view loads so you have to load a view behind it that is a duplicate of the image (more ofter the image is screenshot of the view)
In your case you would need to dynamically generate the default.png when the web page updated. Upon launch it would display the information and buy the time the user read it, made a decision and touched the interface, the real web page would have replaced it.
Of course, this system won't work if you want new info at the start of each launch. Instead you'll have to generate the image during one run for use in the next.
In any case, if you launch into a web page the user did not select, I advise that you create a default.png that displays a message along the lines of "Checking for Updates and Info" (or whatever your doing) so the user won't think your app launched and hung.

Application.DoEvents, when it's necessary and when it's not?

What is the necessity of using Application.DoEvents and when we should use it?
Application.DoEvents is usually used to make sure that events get handled periodicaly when you're performing some long-running operation on the UI thread.
A better solution is just not to do that. Perform long-running operations on separate threads, marshalling to the UI thread (either using Control.BeginInvoke/Invoke or with BackgroundWorker) when you need to update the UI.
Application.DoEvents introduces the possibility of re-entrancy, which can lead to very hard-to-understand bugs.
Windows maintains a queue to hold various events like click, resize, close, etc. While a control is responding to an event, all other events are held back in the queue. So if your application is taking unduly long to process a button-click, rest of the application would appear to freeze. Consequently it is possible that your application appears unresponsive while it is doing some heavy processing in response to an event. While you should ideally do heavy processing in an asynchronous manner to ensure that the UI doesn’t freeze, a quick and easy solution is to just call Application.DoEvents() periodically to allow pending events to be sent to your application.
For good windows application, end user doesn’t like when any form of application are freezing out while performing larger/heavyweight operation. User always wants application run smoothly and in responsive manner rather than freezing UI. But after googling i found that Application.DoEvents() is not a good practice to use in application more frequently so instead this events it’s better to use BackGround Worker Thread for performing long running task without freezing windows.
You can get better idea if you practically look it. Just copy following code and check application with and without putting Application.DoEvents().
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For i As Integer = 0 To 1000
System.Threading.Thread.Sleep(100)
ListBox1.Items.Add(i.ToString())
Application.DoEvents()
Next
End Sub
Imho you should more less never use it, as you might end up with very unexpected behavior.
Just generated code is ok. Things like you are executing again the event handler you are currently in,because the user pressed a key twice etc etc.
If you want to refresh a control to display the current process you should explicitly call .Update on that control in instead of calling Application.DoEvents.

Vista services: Can show form on invisible desktop?

I am attempting to show a form from a service on Vista (using .NET winforms)
Obviously the form would not show to the console user, as services are isolated in session 0.
However the experiment is to see if it is possible to "show" an invisible form and obtain a window handle & message loop
I have tried but when I issue form.Show(), only the form.Load event fires not .Shown or .FormClosing
Is there any way to capture windows messages in this way as a user application would?
I have not attempted to make the service 'interactive' as I do not wish to interact with the logged-on user.
Yes you can show a form on a service's desktop. It will not be shown to any logged in user, in fact in Vista and later OSes you cannot show it to a user even if you set the service to 'interactive'. Since the desktop is not interactive the windows messages the form receives will be slightly different but the vast majority of the events should be triggered the same in a service as they would be on an interactive desktop (I just did a quick test and got the form load, shown, activated and closing events).
One thing to remember is that in order to show a form your thread must be an STA thread and a message loop must be created, either by calling ShowDialog or Applicaton.Run. Also, remember all external interaction with the form will need to be marshaled to the correct thread using Invoke or BeginInvoke on the form instance.
This is certainly very doable but is really not recommended at all. You must be absolutely sure that the form and any components it contains will not show any unexpected UI, such as a message box, under any circumstances. The only time this method can really be justified is when you are working with a dubious quality legacy or 3rd party tool that requires handle creation in order to function properly.