Solved

Delphi: Keeping a Form on top

Posted on 2004-09-30
12
366 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Expert Comment

by:ZaSz
ID: 12202468
0
 
LVL 34

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
 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
How to Install VMware Tools in Red Hat Enterprise Linux 6.4 (RHEL 6.4) Step-by-Step Tutorial

735 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