Solved

"Always on top" with several forms

Posted on 2001-07-19
21
3,703 Views
Last Modified: 2012-05-04
Hi

I've got 2 forms: Form1 and Form2
when I set Form1's 'FormStyle' property to 'StayOnTop' Form1 stays on top of any other on the DESKTOP
(just like I want it to). However, if I set Form2's FormStyle property to StayOnTop Form2 still stays
(always) hover Form1 but they both stay below any other window (other application) that comes along.

I want the forms to be independent from each other (to set one of them to stay on top of any other
window in the desktop, or to set both of them to stay on top of any other window in the desktop) and
to be selected independently (when I select one of them it should come to the foreground leaving the
other form in the Z order in wich it was).


I got this far:

I've set the 'ParentWindow' property as follows:


     parentWindow := getDesktopWindow;
     parent := nil;

and this seemed to had worked. The only problem now is that both forms can't seem to get focus.


I'm not sure this is the right approach...


    Thanks in advance

      Filipe
0
Comment
Question by:filipecorreia
  • 7
  • 4
  • 2
  • +6
21 Comments
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
I can't reproduce your problem...
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
try this in somewhere event (not tested)

SetWindowPos(Form2.Handle,hwnd_Topmost,0,0,0,0,swp_NoMove or swp_NoSize or swp_NoActivate);
0
 
LVL 21

Expert Comment

by:gemarti
Comment Utility
Set Form2.Visible := true in Form1.OnActivate;
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
Epsylon: what's the part you can't reproduce?


kretzschmar: I had already tried that... no luck


gemarti: No result when I apply your suggestion. What exactly was your idea?
0
 
LVL 13

Expert Comment

by:Epsylon
Comment Utility
Maybe I just don't understand your question...
0
 
LVL 44

Expert Comment

by:CrazyOne
Comment Utility
Well with one of them you could use a timer forcing that form to stay on top but if you use a timer for both them they will continuely flip-flop, which I imagine that is not the desire affect you want.


The Crazy One
0
 
LVL 44

Expert Comment

by:CrazyOne
Comment Utility
>>>The only problem now is that both forms can't seem to get focus

Umm I believe only one form at a time can get focus.
0
 
LVL 1

Expert Comment

by:alx512
Comment Utility
If you use ShowModal function replace it to Show;
0
 
LVL 27

Accepted Solution

by:
kretzschmar earned 220 total points
Comment Utility
found this in the paq (from dumani)

--paste begin

Application.OnDeactivate := OnTop;

procedure TForm1.OnTop(SendeR: TObject);
begin
 SetWindowPos(form2.handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOSIZE);
end;

that will be real stayontop form for child forms...

--paste end

assign the ontop procedure in the formcreate-event of form1 to the application.ondeactivate-event

hope this helps
(not tested by maself)

meikl ;-)

0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Maybe this helps?

type
  TForm1 = class...
    ...
    procedure CreateParams(var Params: TCreateParams);
  end;

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := (Params.Style and (not WS_CHILD)) or WS_POPUP;
  Params.WndParent := 0;
end;

Try this instead of your...

    parentWindow := getDesktopWindow;
    parent := nil;

... code. Does it make things better?

Regards, Madshi.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 17

Expert Comment

by:geobul
Comment Utility
Hi,
kretzschmar's solution does the job. You can even write:

procedure TForm1.OnTop(SendeR: TObject);
begin
  SetWindowPos(form1.handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOSIZE);
  SetWindowPos(form2.handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOACTIVATE or SWP_NOSIZE);
end;

and everithing is OK for me.

Regards, Geo
0
 
LVL 6

Expert Comment

by:MannSoft
Comment Utility
Wow I have wondered how to accomplish this for a long time.  I had messed with SetWindowPos but always placed the code in the form's OnDeactivate event which never seemed to work.  I never even thought to place it in the applications OnDeactivate event!

Geez now I feel kind of guilty, getting the answer and not spending any points :-)
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility

Hello experts!


-----------------
CrazyOne:

a) I don't want to use a timer (even if I could find a way to use one) because I'm afraid it may
become all too slow.

b) >>Umm I believe only one form at a time can get focus.
   Of course I mean one at a time...  ;)

-----------------
kretzschmar:

I've had already tried that... and I get the same behavior. But your post gave me another idea...
I followed what you said and have putted the 'Application.OnDeactivate' pointiong to the same function
as 'Form2.OnDeactivate' making the forms stay above any other on the desktop when I switch beetween apps.

..but here's something else I must solve (check out my next post)...

-----------------
Madshi:

I'm not realy using delphi (but borland's C++ builder) so I found some difficulties trying
out your code (that 'inherited' part specialy).
Anyway... I ended up making a Window's API call like this:


SetWindowLong(Form1.Handle, GWL_STYLE, (GetWindowLong(Form1.Handle, GWL_STYLE) and (not WS_CHILD)) or WS_POPUP);
Form1.ParentWindow=0;


I think it does just about the same as the code you posted (please correct me if that's not right).

I got a very weird behavior:
First I tried to put this code in a button. and when I pushed it the form just
disapeard!!! it was still drawn on the screen but when i refreshed that part of the screen (draging any
other window hover it) reveald that it actualy wasn't there anymore.
I've also tried to put the code in the form's constructor. This way the form doesn't disapear but the
form's borders do.

Using this last way I managed to do my testings but the form's still have the same behavior...

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


  Filipe
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
Now there is only one problem left:
supposing that I have't (yet) made the forms be 'always on top'...

Imagine that form1 is beind other app's window and form2 is visible. When I click form2, the other
form(form1), should NOT come to the top of the other app's window.

This problem would (supposely) be solved by the code I mentioned

"    parentWindow := getDesktopWindow;
    parent := nil;  "

putting each form independent of each other when selecting any of them.


Do you any other way to accomplish this?


 Thanks in advance


PS:
   MannSoft: If you feel so guilty you can always post a blank question and accept whatever answer I post...  
there is... If you just can't take it...   ;)
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
no suggestions?
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
Madshi: do you think that what I did is the same as the code you posted?
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
No, not exactly, but I don't know BCB so deep. And I also don't know (at all), whether my suggestion would really help you, if you could use it exactly like that in BCB...  :-(

Regards, Madshi.
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
no further suggestion, and now?
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
Hi!

kretzschmar: I will give YOU the points. but I won't give you the highest grade because:

 you just gave me an idea that helped me to get to the real sollution and

 you cannot give me any hint to how to solve the part of the problem still missing.


Are you all right with that?



 bye

   Filipe Correia
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
do as you want to do, its your decission, and i will accept it, but please no D-Grade :-)
0
 
LVL 1

Author Comment

by:filipecorreia
Comment Utility
Sorry..  it just wouldn't be right to give you any other grade.

 bye
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

744 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

15 Experts available now in Live!

Get 1:1 Help Now