0

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.

Mahan
  • 135
  • 7
  • DLLs are what you're looking for – Delphi Coder Nov 10 '22 at 09:33
  • "_not respounding_": then wait in a thread. Also: just because a file starts to exist there's no guarantee data to it has finished being written entirely - think of writing a 2 GiB big file - it will surely take a while and not be done in the instant it starts to exist. [Displaying other processes as windows of the own one is possible](https://stackoverflow.com/q/3459874/4299358). – AmigoJack Nov 10 '22 at 09:41
  • Just expose the PDF conversion code in a DLL and consume it from your Delphi app, implementing any GUI in your Delphi code. – David Heffernan Nov 10 '22 at 09:44
  • But I want to use the same GUI written in C#. That's why I tend to call another exe file in my app. – Mahan Nov 10 '22 at 11:07
  • I think it could be a way to set the parent of the main form of the exe file to my main form in delphi using windows API for example, and then change the FormStyle to MDIChild something like this. Does it work? And think about Modal as well. – Mahan Nov 10 '22 at 11:13
  • Take a look at https://www.remobjects.com/hydra/ – RaelB Nov 10 '22 at 23:11

1 Answers1

0

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;
Ehab
  • 284
  • 1
  • 9
  • It is a good idea. I think I can show a Delphi empty form as modal and put the ShellExecute command in the FormShow. The question is, can I send the handle of the empt form to C# by parameters and C# form places itself in the empty form? Something like setting the parent to the given handle? The c# form can be borderless and the delphi empty form would be it's border. Does it work? – Mahan Nov 10 '22 at 13:57