Solved

Delphi: Keeping a Form on top

Posted on 2004-09-30
12
336 Views
Last Modified: 2010-04-05
I have an application that has a main form, and several other forms that are triggered (form.show) by buttons on the main form.

The main form runs more or less full screen (either maximised or as a window taking most of the desktop area).
Any pop up forms need to stay on top. You can have one or more pop-up forms open at any given time, and be able to work with either pop-up form.

The main form's FormStyle is set to fsNormal and all popup forms are set to fsStayOnTop. The popup forms can't be called by ShowModal because you may be working with several popup forms at any given time.

The following problem occurs intermittantly, on some computers more often than others.

The pop-up windows tend to disappear behind the main form, either immediately after calling form.show or after 5 or 10 seconds. The only way to get them back is to move the main form out of the way and click to regain focus, or to call the form.show method again from the main form (both unsatisfactory).

I want the pop-up forms to stay on top of the main form no matter what., I thought this is what the fsStayOnTop setting was for, but it does not work as expected.

There is a TTimer component on the main form which updates the main form every 2 mins, but the pop-up forms dissappearing do not appear to be linked to this.

Any thoughts on this would be appreciated.
0
Comment
Question by:harveykane
12 Comments
 
LVL 6

Expert Comment

by:vadim_ti
ID: 12196180
it is like some side effect in your application
stayOnTop must work as expected
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12197138
what about this code for the pop-up form:

unit Unit2_Q_21151827;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm2 = class(TForm)
    Edit: TEdit;
  private   { Private declarations }
    procedure CreateParams(var Params: TCreateParams); override;
  public    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
  inherited;
  with Params do
    ExStyle := ExStyle or WS_EX_TOPMOST;
end;

end.
0
 
LVL 12

Expert Comment

by:Ivanov_G
ID: 12197430
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    procedure OnShowWindow(var Msg: TWMShowWindow); message WM_SHOWWINDOW;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Self.FormStyle := fsStayOnTop;
end;

procedure TForm1.OnShowWindow(var Msg: TWMShowWindow);
begin
  if not Msg.Show then
    Msg.Result := 0
  else
    inherited;
end;

end.
0
 
LVL 1

Expert Comment

by:ZaSz
ID: 12202468
0
 
LVL 33

Expert Comment

by:Slick812
ID: 12203101
hello harveykane, I am guessing from your description, that your Pop-Up Forms, are some sort of "Tool window" functional forms used only with your program, if so, the fsStayOnTop may not be what you want to use, for secondary forms Form2, this fsStayOnTop seems not to go correctly sometimes? I have programs with small Pop-Up tool windows, that were Always ontop of the main Form, (but NOT on top of ALL windows, just main form), by using this code -


code for "Tool" form -



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

var
  Form2: TForm2;

implementation

{$R *.DFM}

uses GrafEdit1; // main form

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
//Params.Style := (Params.Style and not WS_CHILD) or WS_POPUP;
Params.WndParent := Form1.Handle;
// Params.WndParent will make it always on top of that form
end;

 = = == = = = =  = = = = =  = = = =  = = = =  = = = = =

code for main form -


implementation

{$R *.DFM}

uses toolForm;


procedure TForm1.but_ShowToolClick(Sender: TObject);
begin // button click
if not assigned(Form2) then
  Application.CreateForm(TForm2, Form2);
Form2.Show;
end;


 - - - - - - - - - - - - - - - - - - - - - - - - -  --

ask questions if you need more information
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Expert Comment

by:Binsky
ID: 12235067
using the formstyle property fsStayOntop can cause some strange behaviour, I also advise using the SetWindowPos call to put (and keep) your forms on top, without them disappearing to the background when clicking somewhere else.

The line of code needed :
SetWindowPos(YourForm.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE+SWP_NOSIZE);

I had the same annoying problem, and this solved it for me...

Good luck!
0
 
LVL 2

Expert Comment

by:cula99
ID: 12247937
Set Main form FormStyle to fsMDIForm leave rest as it is and that's it.

Čula
0
 
LVL 2

Expert Comment

by:cula99
ID: 12247956
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Panel1: TPanel;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses Unit2, Unit3, Unit4;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Show;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Form3.Show;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Form4.Show;
end;

end.

unit Unit2;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm2 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

end.


unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm3 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

end.

unit Unit4;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm4 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

end.

object Form1: TForm1
  Left = 195
  Top = 107
  Width = 870
  Height = 640
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsMDIForm
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
    Left = 16
    Top = 32
    Width = 75
    Height = 25
    Caption = 'Button2'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 96
    Top = 32
    Width = 75
    Height = 25
    Caption = 'Button3'
    TabOrder = 1
    OnClick = Button2Click
  end
  object Button3: TButton
    Left = 176
    Top = 32
    Width = 75
    Height = 25
    Caption = 'Button4'
    TabOrder = 2
    OnClick = Button3Click
  end
  object Panel1: TPanel
    Left = 16
    Top = 88
    Width = 817
    Height = 481
    Caption = 'Panel1'
    TabOrder = 3
    object Label1: TLabel
      Left = 16
      Top = 8
      Width = 32
      Height = 13
      Caption = 'Label1'
    end
    object Edit1: TEdit
      Left = 16
      Top = 24
      Width = 121
      Height = 21
      TabOrder = 0
      Text = 'Edit1'
    end
  end
end

object Form2: TForm2
  Left = 89
  Top = 232
  Width = 306
  Height = 267
  Caption = 'Form2'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsStayOnTop
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end

object Form3: TForm3
  Left = 950
  Top = 168
  Width = 223
  Height = 730
  Caption = 'Form3'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsStayOnTop
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end

object Form4: TForm4
  Left = 122
  Top = 761
  Width = 945
  Height = 193
  Caption = 'Form4'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  FormStyle = fsStayOnTop
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end
0
 
LVL 1

Expert Comment

by:fidel83
ID: 12859768
hey harveycane, just use this in the child form's show method:

SetWindowPos(Handle,HWND_TOPMOST,Left,Top,Width,Height,0);
SetForegroundWindow(Handle);
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 13442911
PAQed with no points refunded (of 100)

modulo
Community Support Moderator
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now