Jump to content
McScotty

Delphi 2007 to 10.3 and Windows 10 taskbar issue

Recommended Posts

So I think that this behaviour happens because the window is not destroyed.  If you make the analagous WinForms app then you don't see this behaviour.  I believe that's because that framework destroys the window when the modal dialog is closed.

 

You can achieve the same thing by, guess what, destroying the form object.  That's really the best approach.  I can't stress strongly enough that's what you should do.

 

You could also achieve the same effect by forcing the window to be destroyed.  Call DestroyWindow on the modal form when it closes.  That forces windows recreation the next time you show it.  Perhaps that's safe to do.  I wouldn't do it.  I'd do it the right way.

 

Embarcadero are never going to "fix" this because it would require a complete redesign of the VCL.  Not going to happen.  

  • Like 1

Share this post


Link to post

I have tried various application.mainform.handle and just application.handle   To be fair I am a bit  mixed up as it works differently in 10.3 than it does in 2007, not sure what way around it is, but either way, it certainly looks like it works.

 

I would just like to know by doing so, it fixed the issue and is not likely to cause anything else to go wrong.

 

Thanks.

Share this post


Link to post

I don't understand what you mean with these two handles. I guess you are talking about the popup parent. You can set this more easily with the VCL PopupParent property. The right thing to set it to is the main form. 

 

Do you understand what the popup parent is, aka window owner in Windows terminology? 

Share this post


Link to post

Hi David.

 

I did try setting popupparent to the main form, but that makes no difference either, but to be fair, it is a property that I have ignored, and actually thought it had to do with popup menu's until I looked into it.

 

What I was referring to was that on each dialog window, if the creating is overriden by adding a CreateParams as follows, that seems to fix the issue, but I am unsure why, or if this is a safe way to get round the issue.

 

procedure TOKRightDlg.CreateParams(var Params: TCreateParams);
begin
  inherited;
 Params.WndParent:=application.Handle;
end;

 

I appreciate that closing down the dialog is a valid way to get round the problem, and if Embarcadero will not fix this in Widows 10, I am happy to live with a work-around.  I can largely do this by freeing the dialog, but on some, I would prefer not to have to do it, as I never had to do it before on Windows 7.  I am happy to put the above in the get round the issue if I can't or dont want to free the dialog, providing it is safe to do so.

 

I would even settle for an option to turn of the live thumbnail preview of just my app, is that an option at all? 

Share this post


Link to post

You don't want to make the application window the popup parent. Then your dialog can appear behind the main form. You want the main form to be the popup parent. Which you can do in CreateParams, or by setting PopupParent.

 

It's important that you understand what popup parent aka Window owner in Windows terminology means. At the moment you seem to be trying stuff without understanding it. 

 

I think I already explained that destroying the window is the key to getting the behaviour you want. I gave you two options for doing that. 

  • Like 2

Share this post


Link to post

Maybe I am not making myself clear.

In the properties of the dialog, I set PopUpParent := Form1, is that that what I am supposed to do?  Not the main form.

Regardless, doing this does not solve the issue that I have discovered,.  The code I put in CreateParams does however.

Share this post


Link to post

But when you make the application handle the popup parent, there's nothing to keep the modal form on top of the main form.

 

This conversation is going nowhere. You really do need to understand what popup parent is. 

  • Like 1

Share this post


Link to post

My understanding of the PopUpParent is that I can use it or I can use CreateParams and set the WndParent myself which results as the same thing.

 

If I set the PopUpParent to the main form it appears correctly, but still suffers from the showing the dialog in the thumbnail preview.

 

However if I use CreateParams and set 

 

Params.WndParent:=application.Mainform.Handle;

 

This does not suffer from the issue with the thumbnails.  Why is it behaving differently?

Share this post


Link to post

Yes sure.  Example 1 is the one with the issue on the taskbar, run the code and click on button then OK dialog.  hover mouse over taskbar and then the thumbnail image and you will see the closed (hidden) dialog is now visible, but will disappear again if you click on the thumbnail.

 

Example 2 is the same code, but the dialog has been modified to override the create process by adding Params.WndParent:=application.Handle;  Run the code as above and voila, no dialog is shown in the taskbar.

Example1.zip

Example2.zip

Share this post


Link to post
7 hours ago, David Heffernan said:

You don't want to make the application window the popup parent. Then your dialog can appear behind the main form. You want the main form to be the popup parent

This is a really important piece of information. Thank you!

Share this post


Link to post
18 hours ago, McScotty said:

Yes sure.  Example 1 is the one with the issue on the taskbar, run the code and click on button then OK dialog.  hover mouse over taskbar and then the thumbnail image and you will see the closed (hidden) dialog is now visible, but will disappear again if you click on the thumbnail.

 

Example 2 is the same code, but the dialog has been modified to override the create process by adding Params.WndParent:=application.Handle;  Run the code as above and voila, no dialog is shown in the taskbar.

Example1.zip

Example2.zip

 

20 hours ago, McScotty said:

My understanding of the PopUpParent is that I can use it or I can use CreateParams and set the WndParent myself which results as the same thing.

 

If I set the PopUpParent to the main form it appears correctly, but still suffers from the showing the dialog in the thumbnail preview.

 

However if I use CreateParams and set 

 

Params.WndParent:=application.Mainform.Handle;

 

This does not suffer from the issue with the thumbnails.  Why is it behaving differently?

 

There seems to be some confusion.

 

You asked about why setting PopupParent to be the main form resulted in different behaviour from setting WndParent to the main form handle in CreateParams.

 

However, the two example projects you provided did not differ in that way.  In those projects the only difference is that one of them sets WndParent to be the application handle.  And you'd expect different behaviour in that case.

Share this post


Link to post

My question was that I thought setting PopUpParent was the same (more or less) as setting WndParent in the CreateParams.

 

Clearly that is not the case but I really want to know why setting WndParent corrects a bug in the taskbar thumbnail that a standard Delphi application suffers from ordinarily if the dialog is not destroyed.

Share this post


Link to post
1 hour ago, McScotty said:

My question was that I thought setting PopUpParent was the same (more or less) as setting WndParent in the CreateParams.

It is the same if you do it right. You didn't. Your code set the popup parent to be the application handle. But we were previously talking about making the main form the popup parent. You even had a potldt claiming to have done this but then your code told a different story. 

 

1 hour ago, McScotty said:

I really want to know why setting WndParent corrects a bug in the taskbar thumbnail that a standard Delphi application suffers from ordinarily if the dialog is not destroyed.

It doesn't. Setting WndParent doesn't fix your issue. It is setting WndParent to be the application handle that changes the behaviour. The reason that it changes the behaviour is that with application handle as popup parent then the dialog is not made visible when the main form is made visible. But, as I have explained before, if the application handle is the popup parent then the system won't guarantee that the dialog is always in front of the main form. 

 

I think I've said this a few times before, but I do believe that it's important to understand what popup parent does, and why it is important. My advice to you is to do some research on what popup parent actually is and why it is important to set it, with particular focus on modal dialogs. 

Edited by David Heffernan

Share this post


Link to post
On 10/26/2019 at 1:03 PM, McScotty said:

The reason I use the OnCreate in some forms is to fill comboboxes with names from a database for example.  I only want to do this once per invocation of the form so I just re-use the existing form rather than destroy it and having to go through the same process again every time I want to show the dialog.  Is there a better way to do this that I am not aware of?

I was giong to say that...

On 10/26/2019 at 7:50 PM, aehimself said:

If you want to load data only once, load it into an object in your main form (like a DataSet or a TStringList) and send that to your dialog form with a reintroduced .Create or an additional .Init method.

Yeah. But you do not need to override stuff as that's what the TDataSource component is for. Just put one on each of the dialogs that need to use that data and link it to the dataset on a datamodule... and the opened dialog(s) DB-aware control will update as needed. Then you can create and destroy windows galore. I have seen similar component concepts called SumethingSumehtingLink.

 

Meh... you moved on i see now... sorry, i missed page 2 :classic_blush:

Edited by Dany Marmur

Share this post


Link to post

Solution:


 

 public
    { Public declarations }
  protected
    procedure CreateParams(var Params: TCreateParams); override;




procedure TfrmSubForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := Application.Handle;
end;


 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×