Search code examples
c#delphipinvokeshowwindow

Maximizing an Delphi (VCL) application externally using windows API


I try to start another application that is written in Delphi in my C# application using this code:

Process process = new Process();
process.StartInfo.FileName="app.exe";
process.Start();

It happens that users minimize that another app. So, sometimes I want to bring that window from the minimized state to maximized state, and show on top of my C# application. When I try to maximize it, using Windows API calls:

 ShowWindow(process.MainWindowHandle, SW_MAXIMIZED); -- SW_MAXIMIZED=3

It shows me a black screen instead of application: Effect of ShowWindow

I guess it's due to how VCL applications works. I have tried different approaches (SW_RESTORE, SW_SHOW), then tried to SetForeGroundWindow (also didn't help - it only works when window is not minimized).

What's more, after maximizing it with ShowWindowprogramatically, I can still maximize that external app window from the taskbar manually, and it works. Also when I minimize manually the window, a black window minimizes as well.

If I close that black window, the external Delphi application is being closed too.

After some time wasted today, I found out that sending alt+tab using SendKeys class worked. However, that's a very naive, and I don't accept it as a solution, since user could have any other window opened before (not only an external application), so then that another window will be on top.

Any ideas how to deal with that, or what is actually happening?

I tried to dig in VCL documentation, but I couldn't find proper explanation about what is happening.


Solution

  • Credits go to @RemyLebeau for finding a reason of the problem i described, which also led me to finding a correct solution (found proper window handle instead of what i was finding before). I just copied it from the comment section.

    The 1st window created by a Delphi VCL app is a hidden utility window, not the actual UI window the user sees on-screen. So process.MainWindowHandle is likely picking up the wrong window, which is why you end up maximizing a blank window. The Win32 API has no concept of a "main window", that is an entirely made-up concept in the .NET world, and it doesn't always translate well when dealing with external non .NET processes.

    ... In older Delphi versions, VCL TForm windows are owned by the hidden TApplication window by default. The hidden TApplication window is an unowned window. In newer versions, the old behavior can be re-enabled by setting TApplication.MainFormOnTaskbar=False

    Remy, if you want to post an answer here i will delete mine, i just wanted to post an answer for future visitors.