-1

Trying to find a way to force one of my forms to stay on top of everything else on the desktop even when the main form is minimized. Kind of like google chrome does with its little notifications.

I've set the form style of my form to systemStayOnTop and that works pretty well until I minimize the main form. When I do minimize it though, everything else disappears (as it should, I guess).

So, is there a clean way to force a form on top of everything even when my main form is minimized? Or do I have to delve into DirectX/WinAPI?

P.S. Already been to this question, but those methods didn't work.

Thanks.

NOTE: Even so this question was originally tagged [delphi] it according to the comments below is about Lazarus. That's why there are answers for Delphi.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Michael
  • 548
  • 6
  • 23
  • What is "systemStayOnTop"? How do we know what we may suggest will work while what you have already tried *doesn't work*? – Sertac Akyuz Aug 09 '17 at 19:02
  • Why not disallow minimizing the main form and instead let users close it.. then add a button on the StayOnTop form that shows the main form? – John Easley Aug 09 '17 at 19:19
  • @SertacAkyuz, `systemStayOnTop` is an identifier for a variable of type `TFormStyle` that you set into the Form Style property of the form. Here's more [info](http://lazarus-ccr.sourceforge.net/docs/lcl/controls/tformstyle.html) – Michael Aug 09 '17 at 21:15
  • @SertacAkyuz, "How do we know what we may suggest will work while what you have already tried doesn't work?". I think that's the whole point of stackoverflow. I simply am not experienced enough in this area and don't know all the potential techniques that one can apply in this situation. I merely done the basic stuff that is within my reach. Maybe people that have worked in this area can help me. – Michael Aug 09 '17 at 21:19
  • 2
    @Michael - That link is to lazarus documentation, not delphi - where there's no systemStayOnTop. Please tag your question correctly. – Sertac Akyuz Aug 09 '17 at 22:19
  • You should be able to see my point. You have tried suggestions from others that didn't work, which have been reported to work. What guarantee do you have that our suggestion's will work? You should provide a [mcve] and then we could see what fails and how. – Sertac Akyuz Aug 09 '17 at 22:21
  • 2
    Lazarus <> Delphi when it comes to form properties. In Delphi, there is no `TFormStyle.systemStayOnTop`.Tagging it Delphi wastes the time of people who answer it only to find out that you're not using Delphi at all. – Ken White Aug 09 '17 at 22:45
  • Really sorry for confusing tags here, guys. Thankfully, it's been edited. I'll be trying to work this thing out later. – Michael Aug 10 '17 at 21:35

3 Answers3

3

You can force the form to stay on top by setting the FormStyle to fsStayOnTop and also making it a top level window and setting the appropriate window style. You can do this by overriding CreateParams in your form :

TForm1 = class(TForm)        
  private
    { Private declarations }
  protected      
    procedure CreateParams(var Params: TCreateParams); override;
  public
    { Public declarations }
end;

implementation :

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.WndParent := 0;  { Make this a top-level window }
  Params.Style := WS_POPUPWINDOW or WS_CAPTION or WS_CLIPCHILDREN;
end;
J...
  • 30,968
  • 6
  • 66
  • 143
  • Hay J, thanks for the answer! Unfortunately, I'm using Lazarus, and it appears that the procedure `CreateParams` is not present in the parent class. – Michael Aug 09 '17 at 21:06
  • @MichaelNaifield Well why did you tag it Delphi if you want an answer for Lazarus? Add `LclType` to your uses clause, the definition for `TCreateParams` is probably missing. – J... Aug 09 '17 at 22:01
  • @MichaelNaifield Lazarus also does stupid things in `TWin32WSCustomForm.CreateHandle` in `Win32WSForms` where it forces a parent even if you tell it you want none. You can either re-implement that or modify the lazarus source to do something sane. This answer works in Delphi. – J... Aug 09 '17 at 22:49
  • 3
    It's the height of impoliteness to wait until we have made the effort to answer the question you asked before telling us that you omitted the most significant details from the question. There is nothing "unfortunate" here. It's just downright sloppy. Make sure you ask the right question. Don't rush. – David Heffernan Aug 10 '17 at 05:26
0

I tried the CreateParams solution posted above - in Delphi 10.3.3 - and it did not work. However, I did find a solution that works for Delphi. No idea if there is something similar in Lazarus, but I am posting the Delphi answer here in case anyone else happens upon this since I found this post 30 minutes before I found the Delphi answer that worked. :)

Put this in the "Form B" OnCreate event:

FormStyle:= fsStayOnTop;

but that alone isn't enough...

Drag a TApplicationEvents onto your "Form B"

In the OnDeactivate event for ApplicationEvents1, add the following:

SetForegroundWindow(Handle);

I keep an eye on a small status window while my main form is crunching data out of site. Works beautifully!

Mad Martian
  • 109
  • 6
-1

In addition to @J...'s post, you could use the OnDeactivate procedure from TForm class to force user to not loose focus from the window.

When creating and showing a form, you can also use ShowModal instead of just Show to make the Window appear on top of parent.

  • I never make a call to `Show`. My form is always visible, I'm fading its `alphaBlendValue` in/out with timers in order to show it. – Michael Aug 09 '17 at 21:23
  • You already tested `onActivate` event? It should be triggered when your form finishes alpha. It's solution based on hard code into some form events. – André Paul Grandsire Aug 10 '17 at 12:19