How to open an external App as MDIChild or Modal Dialog in my App as if it is another form of my App

385 views Asked by At

My company has a huge with-delphi-written 3-Million-line-code mostly-database-related Application, and we are responsible to support this program. This Application has a MainForm as fsMDIForm and other forms are fsMDIChild which are created programmatically when they are needed. In our team, we have worked with other different programming languages like C++, C#, Python, VB, etc. An idea is to make some part of the program with another programming language like C# in Visual Studio and open it in our App. For example in another C# project in our company we have a form which lets user select a convartable-to-PDF file (such as pictures, documents, ...) with special GUI and convert it to PDF/A for archiving. It allows user to attach multiple PDFs as well. Now the project manager has told us to use this code in our Delphi project. There are many ways to do so, such as making a DLL and call it from Delphi or simply convert it to EXE and call it from Delphi and wait for it to be closed and so on. Sometimes writing it again in Delphi is the only solution, but it would be great, if I would put such a code in a simple C# project and make an EXE from it, then I run this EXE file as Modal/MDIChild-Form in the Delphi application, as if it is a part of the main App.

What an absolutely bad thing I did:

procedure TEditEmailDlg.btnAttachFileClick(Sender: TObject);
var
  tf: string;
begin
  tf := TempFolder + 'FCDAA5F7-E26D-4C54-9514-68BDEC845AE3.Finished';
  ShellExecute(Handle, 'open', 'C:\Program Files (x86)\GL-K-S\tools\2PDFA.exe', '', '', SW_SHOWNORMAL);
  repeat
    Sleep(300);
  until FileExists(tf);
  with TStringList.Create do
  begin
    LoadFromFile(tf); // Selected and converted filenames
    ...
  end;
  ...
  DeleteFile(tf);
end;

As you see it waits for the App to be closed, but it is not like a MDI form of the project and the project is going to be not respounding. If it is a good idea, please let me know how can I do it, and if not, why and what is the better solution to prevent rewriting forms and codes behind them in Delphi.

1

There are 1 answers

1
Ehab On

As you have the code of both Delphi (D) and C# or C++ (C) you can do a little modifications on both applications to use either Windows Messages or Shared Memory.

I used Windows Messages 10 years ago, sorry I don't have the code right now.

  1. Windows Messages :
    D will send a window handle (WH) to C as a command parameter when running it. When C finish or any other reason, it will notify D by sending a custom message to WH.

  2. Shared Memory :
    D will send the name of shared memory to C as a command parameter when running it.

In both cases C will send back a window handle (WH2) to D, then D will use SetParent() function to make MyForm inside D is the parent for this window WH2.

SetParent(WH2, MyForm.Handle);
MoveWindow(WH2, 0, 0, MyForm.ClientWidth, MyForm.ClientHeight, True);

D will close MyForm when it get a notify message from C telling it that C is about to close.

You may also use GetWindowRect() function to get width and height of WH2 to adjust MyForm size. var r: TRect;

GetWindowRect(WH2, r); 
MyForm.ClientWidth := r.Right - r.Left;
MyForm.ClientHeight := r.Bottom - r.Top;