1

I recently got a new development computer with again 2 monitors, but unfortunate it has windows 10.
Now I also have some tools still developed in Delphi 7 and they work but with one annoying problem.

When I start an Delphi 7 application the icon on the taskbar does not move to the second monitor.
The taskbar is setup to show icons on the taskbar of the monitor they are open. This works for all applications, except for the Delphi 7 applications.
The icon always stays on the primary monitor.

I have the source available, so I wonder is there something I have to put into the source code, or setup some property, to get this working ?

Googling this bring up lots of cases where the form does not moves to the second monitor, but I did not find anything about the icon on the taskbar.

GuidoG
  • 11,359
  • 6
  • 44
  • 79
  • The icon is for the hidden application window which is always on the primary monitor. This is what "MainFormOnTaskbar" changed. You can set it manually so with various side effects. – Sertac Akyuz Jan 14 '19 at 16:09
  • 1
    "*This is what "MainFormOnTaskbar" changed*" - that is what it *originally* changed, per its name. Then they went overboard by applying it as the trigger to change a whole bunch of other things that had nothing to do with the Taskbar at all, making its name much less meaningful. Now it acts more like something that should be named `UseVistaSemantics` instead. – Remy Lebeau Jan 15 '19 at 02:13

1 Answers1

5

This is because the window handle associated with the taskbar button is the window handle owned by the Application object rather than the window handle of your main form.

In later versions of Delphi you would write Application.MainFormOnTaskBar := True in your .dpr file and that would change behaviour so that the taskbar button was associated with your main form instead. I believe that MainFormOnTaskBar was introduced in Delphi 2007.

Migrating to a modern version of Delphi is the ideal way to solve the problem. If you cannot do that then you'll need to hack your way around the VCL code to ensure that the main form's window handle is the one associated with the taskbar button. That's not likely to be an easy job. Fundamentally, you are paying the price for continuing to develop with tools that are long out of date.


As Remy points out there isn't much hacking required to do the bare minimum. Change the window style of the Application window to remove the WS_EX_APPWINDOW style, and have the main form override the CreateParams method to set its owner window to NULL, i.e. Params.WndParent := 0.

I suspect that the behaviour will not be quite as smooth as you'd get with a modern VCL app. For instance, the VCL has been modified to reduce the amount of window recreation it does which is more important now that the main window is associated with the taskbar button.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I would prefer to migrate these tools to Tokyo, but since they are used only internal in our organization and only by developers, they somehow keep at the bottom of the priority list... – GuidoG Jan 14 '19 at 16:17
  • So it's probably not worth hacking the VCL either – David Heffernan Jan 14 '19 at 16:19
  • If I understand correct its going to take lots of hacking, so it might take just as long time then migrating. Unless you have a good documentation on how to do it – GuidoG Jan 14 '19 at 16:21
  • No documentation, lots of things to consider. Follow the link in the comment to this [answer](https://stackoverflow.com/a/4241429/243614). Also read the question itself, there are other behavioral changes fixing this would bring. – Sertac Akyuz Jan 14 '19 at 16:29
  • Obviously I don't know any details of how hard either option would be, but I'd expect it would be hard to make a case for spending time hacking. It's just a dead end. If you migrate then you end up with a tool that can be developed further. – David Heffernan Jan 14 '19 at 16:35
  • 1
    It is really not very hard at all to fix this issue, and it doesn't require hacking the VCL, either. Simply change the window style of the `Aplication` window to remove the `WS_EX_APPWINDOW` style, and have the `MainForm` override the `CreateParams()` method to set the Desktop as its owner window. A common solution posted hundreds of times before. This can all be done in app code without messing with VCL internals. – Remy Lebeau Jan 15 '19 at 00:40
  • @Remy Well, you mean set 0 as the owner window – David Heffernan Jan 15 '19 at 06:42
  • @RemyLebeau Thanks that worked. Maybe you should post this as an answer – GuidoG Jan 15 '19 at 08:25
  • @DavidHeffernan I used this `Params.WndParent := GetDesktopWindow;` – GuidoG Jan 15 '19 at 08:35
  • Don't. Pass 0. Don't rely on Windows correcting your mistake. – David Heffernan Jan 15 '19 at 08:40
  • @GuidoG see [What’s so special about the desktop window?](https://blogs.msdn.microsoft.com/oldnewthing/20040224-00/?p=40493) – Remy Lebeau Jan 15 '19 at 09:49
  • @Remy Fair to say also that for many years now Windows has defended against this programming mistake and so terrible things don't happen if you set the desktop window as your owner. However, it's still correct to use 0. – David Heffernan Jan 15 '19 at 09:52
  • @RemyLebeau That is an interesting read indeed thank you for that. I still think you should post the createparams code in an answer so i can accept it and it might help others with the same mistake – GuidoG Jan 15 '19 at 09:54
  • You don't think that the instructions here are sufficient? – David Heffernan Jan 15 '19 at 10:04
  • @DavidHeffernan For me they where sufficient yes. – GuidoG Jan 15 '19 at 10:19