"Always on top" with several forms

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
LVL 1
filipecorreiaAsked:
Who is Participating?
 
kretzschmarCommented:
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
 
EpsylonCommented:
I can't reproduce your problem...
0
 
kretzschmarCommented:
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
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
gemartiCommented:
Set Form2.Visible := true in Form1.OnActivate;
0
 
filipecorreiaAuthor Commented:
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
 
EpsylonCommented:
Maybe I just don't understand your question...
0
 
CrazyOneCommented:
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
 
CrazyOneCommented:
>>>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
 
alx512Commented:
If you use ShowModal function replace it to Show;
0
 
MadshiCommented:
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
 
geobulCommented:
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
 
MannSoftCommented:
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
 
filipecorreiaAuthor Commented:

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
 
filipecorreiaAuthor Commented:
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
 
filipecorreiaAuthor Commented:
no suggestions?
0
 
filipecorreiaAuthor Commented:
Madshi: do you think that what I did is the same as the code you posted?
0
 
MadshiCommented:
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
 
kretzschmarCommented:
no further suggestion, and now?
0
 
filipecorreiaAuthor Commented:
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
 
kretzschmarCommented:
do as you want to do, its your decission, and i will accept it, but please no D-Grade :-)
0
 
filipecorreiaAuthor Commented:
Sorry..  it just wouldn't be right to give you any other grade.

 bye
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.