简体   繁体   中英

How to keep a child form on top of everything, but the parent doesn't have to be?

I have seen a few postings that are similar to this question, but this has a subtle difference. I have a program, the user interface of which can sit behind other programs, but it has a child form that is displayed in the top left corner that displays results, this part of the monitor is duplicated and is displayed to the public, it is a "scoreboard". I want this "results" form to sit on top of everything (Taskmanager is OK, I can live with that). Any other applications that would be run will not be trying to climb to the top, eg "Word", "IE", "Excel" etc.

If I set the parent "SetWindowPos" to "TopMost" and the child also to "TopMost", both of my windows are on top, however, the user interface form also sits over anything. If the user needs to start another application, our form will sit over it, making the other application unusable, however, it will sit under our results form. We cannot use a timer to move it to the top as it will be covered until the timer fires, this is not allowed to happen.

If I only set the results form to topmost, it does not stay at the top of everything. It appears that the parent must also be topmost? Is there a way of getting around this and make the child on top, but its parent can sit below? Or does the parent have to be topmost in order to have children also topmost? The parent can not sit over the child as I grab the move event and prevent it moving over the child.

I am programming in Delphi, so any answers would be best in Delphi, but anything more generic is quite ok, I expect it would be a call to Windows anyway.

Thanks

If I understand you correctly, your program has a main form ( MainForm ) and a results form ( ResultsForm ) and probably some other ones too, but those should 'behave' normally.

The MainForm should also behave normally, that is, move to the background if other applications are activated but the ResultsForm should always stay on top of all other forms, also those of other applications.

The following is tested in Windows 7 only, so may or may not work with other OS's. I will later today test with Windows 10.

First outcomment any previous attempts that might interfere. Leave MainForm.FormStyle as the default fsNormal . Set ResultsForm.FormStyle to fsStayOnTop .

Then add a TApplicationEvents to ResultsForm and add an event handler for OnDeactivate :

procedure TResultsForm.ApplicationEvents1Deactivate(Sender: TObject);
begin
  SetForegroundWindow(Handle);
end;

The ResultsForm will now stay on top of other windows, also of other applications.

Caveat : If you start a second instance (or if some other application is doing the same trick) you will end up in a loop where the apps are fighting for being on top.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM