During load of my application I am loading settings and other things, and want to be able to show a message to the user. However this does not work on my Delphi XE6 FireMonkey application targeting iOS (iOSSimulator).
When I call ShowMessage or MessageDlg during program load, it locks, and nothing is shown. It is probably entering the modal state, but since the message is not shown, it is not possible to continue.
Even in the main forms FormActivate, calling ShowMessage does not show anything.
How can I show a message while loading the application?
You can use loading symbol along with Message. It will serve your purpose. You can use "MBProgressHud", you not need to give any extra effort, just pass parameter and it will display loading image along with text. Enjoy!
I am surprised that no one have written about this before and that no Firemonkey users have answered my question.
That you are allowed to call Showmessage during program load, but the app locks if you do it, is not appropriate behavior. In a desktop app, it is quite normal to show a message during program load, in case something fails.
I am converting a 500k line project from VCL to FMX, and since I cannot show a message on iOS, I will have to restructure the create and load code.
The solution I plan to implement is to make failsafe solutions that will allow the app to load no matter what happens, then when the app is running, I can show whatever messages have come up during load (those that the user have to consider).
If anyone have more information or suggestions for a better solution, please comment.
Related
I have developed a Delphi prog which logs into a website, collects "today's number" and displays it on a screen. Having got the data, the only place I could access it was in the final 'download completed' event. This doesn't seem right, as there seems to be no way to get away from the string of 'completed' events. The program never returns from the WB.Navigate call. WB.Stop and WB.Quit seem to refer to browser activity. I want a WB.TERMINATE or something! It's OK for now, but I want to put the web access in a loop, and with the current technique it just burrows deeper into the stack etc. I assume it's running in a separate thread, but can find no info about this. Should I put the browser component on a separate form created at run-time? Would freeing the form tidy things up? Any advice would be appreciated.
EDIT: Thanks for early responses. I must have had a senior moment. In fact the WB.Navigate call does return. The IDE tells me that it launched a thread with the web navigation request. So it's down to me to do some internal synchronizing to check the data arrival. Yes, the data is on the web page not a download. There is no API. I could have done basic searching of the web pages but it's 3 levels deep. The component made it easier to select the wanted data. All good now. Sorry for wasting your time.
We had to use CoFreeUnusedLibrariesEx for fixing a bug with heap not being cleared after using a MSXML library
Refer this link:
http://blogs.msdn.com/b/marcelolr/archive/2008/11/13/msxml-heaps-not-being-released.aspx
But this caused another issue with TTimers which takes while to show up and disappears when Delphi app is bounced and again shows after a while.
This app uses TTimers to schedule it's job like running a XML transform .
Here is the issue:
When TTimer.Enable is called it throws an error not enough Timer available.
I know this is a masked error and I would have to figure out how to get to the actual error.
This is a single threaded application with only one timer.
Here are the links I looked into
Most Common reason seems to be invalid windows handle
https://groups.google.com/forum/#!topic/borland.public.delphi.winapi/UrIskaFZggU
There are other threads that suggested that OS ran out of resources for TIMERS I'm not sure if that is relevant to me.
I'm Just trying to understand what is Interaction between CoFreeUnusedLibrariesEx and TTimers that it gradually some how robs it of resources and makes us bounce the app to get it working.
How do I go about solving this issue , I'm looking for some directions?
CoFreeUnusedLibrariesEx should not affect TTimers. But if loading and unloading a (buggy) dll leaks any user objects (this includes timers, window handles, ...) then I could imagine that you run out of user objects.
Use Windows Task Manager and configure it so it will show the "USER Objects" in the "Processes" tab. Then compare the number of user objects when you call CoFreeUnusedLibrariesEx and when you don't call CoFreeUnusedLibrariesEx.
I'm looking for a line of code in Delphi which can disable sending keys to an application. For example I have a game.exe, I want to disable sending keys to it, so you can not play it.
How to do that? Please Guide me step by step :)
Hiding and blocking input should be separate questions. Your question is so vague that I'm tempted to vote to close it, but here are some general ideas instead;
If you want to block all input from getting to an application,you can simply grab the focus away from that particular application, or keep your window on top and make it full screen. This is often called "Kiosk mode".
You could also forcibly hide all the application's windows.
You could intercept the window messages that are bound for that application and handle them yourself. See the link from Johan on Keyboard hooking.
I have a D2006 app that contains a page control and various grids, etc on the tabs. When I resize the main form (which ripples through and resizes just about everything on the form that is aligned to something), I experience long delays, like several seconds. The app freezes, the idle handler is not called and running threads appear to suspend also.
I have tries pausing execution in the IDE while this is happening in an attempt to break execution while it is in the troublesome code, but the IDE is not taking messages.
Obviously I'm not expecting anyone to point me at some errant piece of code, but I'm after debugging approaches that might help me. I have extensive execution timing code throughout the app, and the long delays don't show up in any of the data. For example, the execution time of the main form OnResize handler is minimal.
If you want to find out what's actually taking up your time, try a profiler. Sampling Profiler could answer your question pretty easily, especially if you're able to find the beginning and the end of the section of code that's causing trouble and insert OutputDebugString statements around it to narrow down the profiling.
OK. Problem solved. I noticed that the problem only occurred when I had command-line switches enabled to log some debug info. The debug info included some HTTP responses that were written to a debug log (a TMemo) on one of the tabs. When the HTTP response included a large block with no CR/LFs the TMemo wrapped it. Whenever I resized the main form, the TMemo resized and the control had to render the text again with the new word wrapping.
To demonstrate:
start a new Delphi project
drop a TMemo onto the form
align it to Client
compile and run
paste a large amount of text into the TMemo
resize the main form
I won't award myself the answer, as I hadn't really provided enough info for anybody else to solve it.
BTW #Mason - would SamplingProfiler have picked this one up - given that the execution is inside the VCL, and not in my code?
A brute-force approach that may give results.... Put a debug message to OutputDebugString() from every re-size event, sending the name of the control as the string to be displayed. This may show you which ones are being called "a lot".
You may have a situation where controls are bumping each other, setting off cascading re-size events. Like 3 siblings in the back seat of a compact car, once they start jostling for position, it can take a while for them to "settle down".
Don't make me turn this car arround....
The debug log (viewable in the IDE, or with an external ODS viewer), may show you which ones are causing the most trouble, if they appear multiple times for one "user-initiated re-size event".
Run your application in AQTime's performance profiler (included with XE, but you can get a time-limited version from their website).
Do some fanatic resizing for a while, and then stop the application.
After that, you'll see exactly which function was called many times, and where most time was spent.
I have a few applications and I call a ShowMessage('Complete!'); at the end of a long operation.
Most of the time, this works great, but every once in awhile, the Message Dialog will show up behind the main form.
Is there any way for me to ensure the ShowMessage will always be on top?
Thanks!
Call the Windows MessageBox() API instead and pass in the handle to the active form. Actually, my code uses Application.MainFormHandle all the time which I am therefore sure is a reasonable and simple approach.
This will have the benefit of being the system native dialog rather than the home-grown Delphi version. It supports clipboard operations also.
If you want to get very fancy then you can use the Vista task dialog, but that's much more complex and you clearly don't need it for such a simple dialog.