2

I'm working on modernizing an old Delphi 7 app for a customer. I already successfully migrated it to Delphi Sydney but the code I'm working with has a ground problem which is all the forms (nearly 200) are shown using Tform.showmodal (and sometimes it could be up to 10 forms on top of each other) which leads me to my problem:

I would like to show on the windows taskbar preview (the one shown when you hover the app) the current form the user is in. Not all the chain of possible forms opened, not the mainform and the last one opened, just the current one.

I've been researching about the Delphi object TTaskbar without much luck as well as the form CreateParams method when the form is shown but the most I've managed to do is to show the chain of all forms opened on the taskbar separately using this code:

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := Params.Style and not WS_POPUP;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent:=application.Handle;
end;

I've also tried to change the mainform on execution (I know it's highly against good practices being a pointer) as a prove of concept, but didn't work either:

Pointer((@Application.MainForm)^) := form1;

Some other researches led me to use the windows messages WM_DWMSENDICONICLIVEPREVIEWBITMAP and WM_DWMSENDICONICTHUMBNAIL to inject straight to the thumbnail the image I want, but that would imply, if I'm not wrong, to regenerate the thumbnail every time the user changes anything on the current form, which I think is not very optimized.

Does anyone know any way to fix this issue without changing the way the forms are shown in the whole application?

plexus
  • 23
  • 5
  • In Delphi 7, there was no `TApplication.MainFormOnTaskbar` property yet, thus all `TForm` windows are owned by the hidden `TApplication` window. So you don't get nice taskbar previews automatically. Since your modal windows are not top-level unowned windows, the VCL messes around with them internally, you likely will have to resort to generating the previews manually... – Remy Lebeau Nov 08 '21 at 17:51
  • ... I once had to add taskbar previews to an MDI app written in C++Builder 6, and ended up having to completely redesign the UI to a Tabbed UI just to accommodate this feature. I don't recall if I dealt with the modality issue or not. But this API is certainly not easy to work with. – Remy Lebeau Nov 08 '21 at 17:55
  • Thank you very much for the info @RemyLebeau I'm afraid I'm going to have ending up doing a massive refactoring of all the showmodal situation – plexus Nov 08 '21 at 20:26
  • If you hide the main form when you show another form, then the taskbar preview will show the second form. Likewise if you hide the second form when you show the third, then again the preview shows the third form. E.g. `procedure TMainForm.Button1Click(Sender: TObject); begin Hide; Form2.ShowModal; Show; end;` – Tom Brunberg Nov 08 '21 at 20:52
  • Hiding the main window isn't a good idea. – David Heffernan Nov 09 '21 at 09:08
  • @TomBrunberg Thanks for your suggestion. Doing a basic test with 2 forms in a new project, once I hide the first form and show the second, the preview thumbnail shows just the icon of the application, not the actual form. Once I hide the second and show the first one again, it comes back to preview the first form. I've tried to set to false the Application.MainFormOnTaskbar property. Also, tried to work with .show and .showmodal methods. Same result in all cases. – plexus Nov 09 '21 at 12:22
  • Hmm. Sorry, I did not tell you that I also removed the `Application.MainFormOnTaskbar := True;` line in the `.dpr` file. Win 10, Delphi 10.4 CE. – Tom Brunberg Nov 09 '21 at 12:46

0 Answers0