Multiple HWND_TOPMOST forms get clipt

Please discuss general Delphi programming topics here.

Multiple HWND_TOPMOST forms get clipt

Postby Stefan » October 21st, 2011, 10:12 am

Hi,

I have an application with a mainform and two other forms.
The MainForm has a button, which when clicked does:

Code: Select all
procedure TMainForm.Button1Click(Sender: TObject);
begin
  Form1 := TForm1.Create(self);
  Form1.Show;
end;


Form1's Position property is set to poScreenCenter.
Form1's Activate procedure is overridden with:

Code: Select all
procedure TForm1.Activate;
begin
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  inherited;
end;


It also has a button with OnClick:

Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2 := TForm2.Create(nil);
  Form2.Show;
end;


The Activate procedure is overridden in Form2 as well, with:

Code: Select all
procedure TForm2.Activate;
begin
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE);
  inherited;
end;


Form2's Position is also set to poScreenCenter.

So, both Form1 and Form2 are in the center of the screen.
Also, Form2 is slightly smaller than Form1, so when Form2 is created (by Form1) it is completely (important!) overlapped by Form1, were it not for the call to SetWindowPos with HWND_TOPMOST which puts in on Top of the list of TOPMOST forms (is my guess).

Form2 is put on top of the list and is shown on top of Form2 and the MainForm. This works well with one minor problem:
When Form2 is shown it is not drawn correctly (or at all actually). The frame of the Form is drawn correctly, but the contents are not, the entire canvas is just a white plain.
The control (a single TEdit) is not drawn untill the mouse cursor moves over it. Any controls that do not have handles (labels, etc) are not drawn at all.

I think the problem is an optimization gone wrong. For some reason Windows thinks it can exclude Form2 from drawing since it is overlapped by Form1. Which is valid, were it not for the fact that Form2 is now the TOPMOST of all TOPMOST forms.

How do I tell the form/Windows that Form2 should be drawn?

Thanks.

Stefan
User avatar
Stefan
Moderator
Moderator
 
Posts: 128
Joined: September 27th, 2004, 9:40 am
Location: Tilburg, The Netherlands

Re: Multiple HWND_TOPMOST forms get clipt

Postby taazz2 » October 21st, 2011, 2:00 pm

have you tried Form2.invalidate or Form2.paint?

What you are describing here does not make sense why would you want to use the topmost windows in the first place. As I see it you are trying to hard to avoid modal dialogs for some reason and I would like to know why maybe there is a better solution.
taazz2
Active Member
Active Member
 
Posts: 22
Joined: September 28th, 2011, 4:21 am

Re: Multiple HWND_TOPMOST forms get clipt

Postby Kambiz » October 23rd, 2011, 6:40 pm

I do suggest to override WM_WINDOWPOSITIONCHANGING and force the second form to be always after the first form. Set AlwaysOnTop flag of the first form at design-time.
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Re: Multiple HWND_TOPMOST forms get clipt

Postby Stefan » October 25th, 2011, 8:44 am

This was a piece of legacy code that I assumed to have worked in some circumstances.
As always the assumption is the mother of all f*** ups.

Calling SetWindowPos() in the constructor or just using plain old VCL fsStayOnTop apparently gives the desired result.

Thanks for your help and good work on SimpleGraph, the both of you :)

Stefan
User avatar
Stefan
Moderator
Moderator
 
Posts: 128
Joined: September 27th, 2004, 9:40 am
Location: Tilburg, The Netherlands


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 2 guests

cron