How to recognize that a form is in focus through event? - delphi-2010

In an application, we have multiple forms. Now we want to refresh a form 'X' when user sees the form 'x' either by restoring it from taskbar or with 'alt+tab'. How to recognize this through event.
The events 'OnActivate','OnShow' get called only once when the form is created. So they are not useful here.

Your claim that the TForm.OnActivate and TForm.OnShow events are fired only once per TForm instance is not true.
The TForm.OnActivate event is fired when a TForm window gains input focus for the first time, and afterwards whenever input focus is transferred to that window from another TForm window, while the app is in the foreground.
Note that there are also TApplication.OnActivate and TApplicationEvents.OnActivate events that are fired when your app comes into the foreground for the first time, and afterwards whenever focus moves to another app and then back to your app.
The TForm.OnShow event is fired when a TForm window becomes visible for the first time, and afterwards whenever that window becomes hidden and then is reshown.

Related

Delphi 11 VCL TTrackBar does not have Tracking property, events fire on each tick change

In Delphi FMX, TTrackBar has two events for tracking changes - OnChange and OnTracking.
Those two events only do the same thing when Tracking is enabled (by default). Disabling the Tracking will make it so that OnChange is only fired after the user is finished.
My problem is that using Delphi 11 for a VCL application, the Tracking property does not exist, and the events fire with each change/tick instead at the end (resulting in sending multiple messages).
I would prefer only the end change / last value), according to this older post:
Delphi TTrackBar doesn't have on complete event
TTrackBar in VCL does not have an event when tracking is finished. However, the underlying Win32 Trackbar control does send such notifications.
It sends WM_HSCROLL/WM_VSCROLL messages (depending on its orientation) to its parent window, where the LOWORD(wParam) is set to TB_ENDTRACK. You can subclass the parent window to handle these notifications.
It can also send a TRBN_THUMBPOSCHANGING notification to the parent window, where the lParam holds a pointer to a NMTRBTHUMBPOSCHANGING struct, whose nReason field is set to TB_ENDTRACK. You can subclass the TTrackBar itself to catch CN_NOTIFY messages to handle this notification.

Wait until a page is fully loaded in WebBrowser Delphi

I am using the code below to wait for a page to be fully loaded when I browse by code, and that works perfectly, but when I click on a link in a page, the WebBrowser1DocumentComplete or WebBrowser1NavigateComplete2 event fires several times if the page contains frames, of JS etc.
I would like to be able to wait for the page to load completely when I click on the link, but I don't know how.
WebBrowser1.Navigate(URL);
repeat
Application.ProcessMessages;
Sleep(0);
until WebBrowser1.ReadyState = READYSTATE_COMPLETE;
First, you should not be using such a loop at all, you shoud be using the TWebBrowser.OnDocumentComplete event to detect when the document is ready.
Second, getting multiple OnDocumentComplete/OnNavigateComplete2 events is expected behavior when frames are used in the HTML. You get an event for each frame, and a final event from the main window.
This behavior is documented on MSDN:
https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768282(v=vs.85)
The WebBrowser Control fires the DocumentComplete event when the document has completely loaded, and the READYSTATE property has changed to READYSTATE_COMPLETE. Following are some important points about the firing of this event.
In pages with no frames, this event fires one time after loading is complete.
In pages where multiple frames are loaded, this event fires for each frame where the DownloadBegin event has fired.
This event pDisp parameter is the same as the IDispatch interface pointer of the frame in which this event fires.
In the loading process, the highest level frame, which is not necessarily the top-level frame, fires the final DocumentComplete event. At this time, the pDisp parameter is the same as the IDispatch interface pointer of the highest level frame.
And even in Embarcadero's DocWiki:
http://docwiki.embarcadero.com/Libraries/en/SHDocVw.TWebBrowser.OnDocumentComplete
Write an OnDocumentComplete event handler to take specific action when a frame or document is fully loaded into the Web browser. For a document without frames, this event occurs once when the document finishes loading. On a document containing multiple frames, this event occurs once for each frame. When the multiple-frame document finishes loading, the Web browser fires the event one final time.
So, in the TWebBrowser.OnDocumentComplete, you need to check the pDisp parameter to see whether it is the IDispatch of the main document or not.

Callback for when the application regains focus back from a redirected app

Is there any way to manage callback when user go through web view and click button - back to app?
You can bind the UIApplicationDidBecomeActiveNotification to an action do whatever you wish when you come back to your application. It should be thrown whenever your application gains back focus for any reason.
Note that this notification will be thrown every time you app becomes active, so make sure to unbind the action after it is called once. Also it will be thrown even if the user does not tap the back button, but goes back to home screen and reopens your app.
You can also use the delegate methods in your AppDelegate class and store the status of the app with some variables to determine when the user comes back to your app.

Can a forms modality be suspended during pascalscript debugging?

Suppose you include a pascal scripting IDE in your application and a script is created that generates a modal form with a button on it and in the button onclick event, you place a debugger breakpoint.
The result, when that button is pressed, will be a deadlocked program that only task manager can kill.
Obviously you don't want to do that, but it would be difficult to control what end users do.
So I was wondering if there was any way to suspend connected modal forms when the pascalscript debugger breakpoint was hit.?
You cannot suspend window modality. It's not a flag.
Modal window runs its own message pump. Which is many levels up in a call stack from the event handler. You cannot change call stack.

Delphi - Simulate Click Animation

This is my first post here on stackoverflow so forgive me for anything I'm doing wrong.
I'm making a kind of guide to the users without any computer knowledge of my application where I show him how to use it by signalizing what he should do, more specifically where to click. I want to that by moving a "fake" cursor to the button and simulate a click, and here is where I got my problem, I have to simulate just the animation of the click, and not the event itself but I couldn't find a way to do that, can anyone help me?
What you're describing is exactly what WH_JOURNALPLAYBACK is for. It populates the message queue with the mouse and keyboard messages you want to occur, and the OS interprets them. In your case, activate the playback hook and perform the mouse events necessary for performing a click.
In preparation, you'll probably want to use WH_JOURNALRECORD to discover what messages you need. Once you have them, you can probably winnow them down to a reasonably sized list prior to shipping your product to customers. (In particualr, you'll probably record many more mouse-move messages than you really need.)
In your button's click handler, check whether playback is active. Only perform the rest of the event handler when playback isn't active. That way, your program will behave just as though the button were clicked (including any animation), but it won't execute the real event code.

Resources