Jump to content
Gary Mugford

Combining several applications into one

Recommended Posts

I have an archaic programming creation structure. For every project I create a folder. Inside that folder, a sub-folder called data and a sub-folder called proj. Within the proj folder, the application's main form is always called frmMain, saved to a PAS file called fMain. The project file is named after whatever I'm calling the program. Usually a short name rather than a full flowered name. i.e. ManifestMgr that runs windowtitle-wise as Manifest Manager version 5. Or somesuch thing. Each sub-form obviously runs separately but many will have a uses FrmMain in the clause.  There are separate utility files that I use across all of my programming, so uses uGlobals, UGProcs and ESBDates are very common. 

 

The development folders are spread across four different drives. I INITIALLY thought to develop using a drive per group, but got sloppy and now any program can be anywhere, although the central utility libraries are with the Delphi install on drive E. 

 

What I want to do now, is to take a selection of those programs and combine them into one. There are three different versions of Delphi involved. My plan is to go through each program and change the FrmMain structure into something more applicable ... FrmMainEncryptedPasswordGenerator, for example. Which means going through all forms on the given example and changing FrmMain to FrmMainEncryptedPasswordGenerator, fMain in uses clauses to fMainEncryptedPasswordGenerator (or more likely, fPWGen). Having done that, I intend to glue the full contents of the folder to the one folder's contents that I intend to be the master program and set up a menu item in it to call on the file FrmMainEncryptedPasswordGenerator as a new sub-form.  I worry that each of the new now-sub forms rather than standalone VCL projects, will have issues with things like auto-create and the such.

 

I am not an accomplished programmer. I slog through things. I have never used pointers. Rarely used classes. Don't think there's an actionlist in the lot. I DO use third-party libraries, but they will call and use whatever tricks they have regardless of the new order in the universe. 

 

So, here's the question ... Anything I should be aware of in my stated course of action?? Beyond the finished product needing to be upgraded to the most current Delphi version of the three. I just want to know if the slow-and-steady process of changing the main form's name to something unique throughout the project and then gluing it into the central calling app, is a reasonable approach. Or might there be a better, faster, less-labour intensive way?

 

Thanks for taking the time to read this and answers are always appreciated. 

Share this post


Link to post

Not sure if that will help you, but meanwhile I changed all my main forms into bare containers with one carrier layout, with no logic inside.
The real views I load as TFrame or TForm into that container then.
This way its much easier for me to manage several versions of .dproj, especially with different platforms and all their special requirements in the projects.
That means creating a new, clean and empty project file now is simple now, and I just need to add one uses entry to point to the real main form in use.

Edited by Rollo62

Share this post


Link to post

What's the problem, in brief? I also have FormMain.pas with TFrmMain in every of my VCL projects. Still can't get why you want to add the project name to the form name. But if you really want it, consider "namespace"-like manner - MyCoolProject.FormMain.pas

Share this post


Link to post

We partly use the same model as Rollo62 does. Functionality that is shared across apps, is implemented as frames.

The amount of work required to create a frame from a regular form, depends on the complexity - but quite often it is more or less just a cut and paste.  

Share this post


Link to post
11 minutes ago, Lars Fosdal said:

We partly use the same model as Rollo62 does. Functionality that is shared across apps, is implemented as frames.

The amount of work required to create a frame from a regular form, depends on the complexity - but quite often it is more or less just a cut and paste.  

Maybe sometimes I avoid copy-and-paste.

Just checking the form and dfm/fmx code, and manually change from TForm to TFrame is more reliable.

Of coarse you need some more settings then after, but with copy-and-paste you loose a lot of relations in the code.

 

But if you like to keep TForm instead of TFrame, you could also keep that, and load a Form in the MainForm.

The advantage is mainly to be able to check and reset project settings fastly, while the forms/frames act only as separate views.

That is more and more imporant, since so many changes occurs in platforms and in every new release, so its better to start new release on a fresh .dproj base.

The separation helps (at least me) to more simply de-couple and test the views separately, as well as to re-use them in other projects.

 

Nowadays I even start simple tests in same way, so that I'M able, after successful test, just to copy my "view" into another project,
so to be able to contol some sub-features, or I can easily replace one implementation with another.

But that of coarse needs more changes than only the separation of the main form ...

 

 

Share this post


Link to post

We are trying to make a habit of assigning events / config in code, and not rely on dfm / unit event handler references. 

Frames are indeed a great way to plugin/unplug code. 

 

Although - I have been told that Frames are not quite as desirable in FMX?

Can anyone offer their experience with FMX and dynamic creation of frames?

Share this post


Link to post

I was hesitating much before I started using them, because of issues in the past.
Now they work fine for me in FMX (I don't use them much in VCL still).

But I use them to separate UI, and I still avoid to make frames "component-like", to introduce them in the components toolbar.
IMHO this cause all the main problems I have seen in VCL, so no "drag-n-drop", but well defined creatin in Code, like you said.
Then I got no problems at all.

I also have a second set where I used TForms instead TFrames, but since TForms are more heavy I prefer to use TFrames now.
Only TForms may have other advantages, like Styling support, but also the TFrames can do that, as long as the main form
has this defined.
So its very open, I think you can use what you like, even Andrea Magni's great TFrameStand contains now a TFormStand component.

Edited by Rollo62

Share this post


Link to post

Lars, Rollo and Frost,

 

  Appreciate your comments in toto. Unfortunately, I wasn't clear. ALL of these applications, save one in Delphi 2010 and a half-dozen in XE7 are in Delphi 7. In creating the umbrella app, I want ALL the source code of the umbrella app and the 74 independent apps in ONE folder. There's a reason for this, I need to bring them all together for Delphi Parser to help change the database backbone. The end result needs to be a case of all the software working with the new backbone,, the apps being menu items in the umbrella main app. It's ballpark three quarters of a million lines of code. And it has to be ONE APPLICATION, ONE FOLDER. Oh, and working in Delphi 7 with an eye towards the lot being transitioned to XE7. 

 

  I LOVE the idea of frames and looked at them. But I didn't use them, preferring composite components. Bad decision. But I've been in the 'Get it to work' business for a long time, once releasing more than 250 updates in a single year (and that was one a day) back in the early days. My employer suffered from the dual scourges of not telling me enough and then having an active imagination when seeing what was possible. But those days of turning in updates two days out of three are long gone. The kludged together main program and all the satellite apps now need merging. Faster the better. I'm stuck on something I managed to change into non-usability back in 2017 but left it like that since the 2015 version of the software worked. Now, I NEED to fix what I broke. But once I get past that, I THINK I have the routine of work down pat. But that leaves me thinking I'm missing something. It's worrisome. 

 

  While not being able to immediately take advantage of your advice, it's in the bank for moving forward.  

 

  Thanks!

Share this post


Link to post

Ok, now it's more clear. I see no reasons why it shouldn't work if you'll have one DPR and thousands of forms. Just rename them in namespace manner and use in umbrella DPR, no auto-create is needed. Just do Application.CreateForm in your umbrella main form's menu onClick handlers. However, you'll have to ensure your under-umbrella apps contain nothing in their DPR but default App.Init/CreateForm/Run.

Share this post


Link to post

Wow, Ok you have a bigger task to do then.

I am lucky not to need to keep on old Delphi, I try always move further to the latest Rx version.

Anyway, your project sounds like a task for big GIT scenario with clever CI.

Good luck.

Share this post


Link to post

When I reached a point like this in the past I always went for a full refactor. It's painful, it's slow, adding no new features at all (maybe even removing some...?) but you always can reuse chunks of code to help to finish faster.

In the end it worths the effort, trust me.

 

I had an application I was maintaining for 10 years (7 threads plus VCL logic written in Unit1.pas, with names like Button1 or Thread1) when I decided that it was too messy. It took about 3 months to rewrite the whole thing from scratch but implementing proper class inheritance and separation of data access, business logic and UI. Adding a new feature in the past took days or weeks, now it is a matter of hours. As an addition, I cannot tell how many bugs were fixed just by cleaning the code up.

 

It's a tremendous and scary job. But knowing the result I'd definitely do it again.

Share this post


Link to post

AE,

 

  Actually, there's a ground-up rewrite using a wholly customizable user interface that I was in the middle of when the breaking of BDE by the Microsoft Windows Update Fall 2017 made continuing to use the app, which dates back to DOS days as a Paradox app and went Windows in the late nineties with Delphi 1, untenable. So, it's past 30 years old and nearer 35 than not. What I think of Microsoft is not allowed to be printed here, I think.

 

  In order to survive until I can get the new software up and running, the plan became to get the app and ALL the satellite apps together and use Delphi Parser (a SHOUTout here for the amazing customer support) to do the backbone switch for me. There's also a gazillion instances of components from companies no longer in business. They have to be replaced along the way too. And I was shocked and dismayed to find I hadn't produced XE7 for my OWN components (merely extensions of existing components with more properties set). When I wrote ComponentKing to find the mish-mashes between D7 and XE7, it found the expected ones missing in XE7 like the long-cherished, but forgotten ABC components from Australia. At least I know what has to be replaced and have a Rosetta Stone of what goes where (technically, what gets replaced by what and WHAT I have to do post swap). And ComponentKing did give me a list of units to un-use via Parser or Replace. So, I've got a decent start. I never used things that trigger spasms from unicode. Replace will do the string/ansistring swap and the assorted cousins.

 

  BUT the whole shebang has to be ready for Parser to do the backbone swap and for me to have the app working lickety split. I've never had a single day of parallel testing and the longest beta test on record was one day. I'm expected to be functionally perfect (acknowledging I might not catch EVERYTHING ... until day two).

 

  I would follow your advice in other circumstances. But I agree with it one hundred percent.

 

  Thanks, GM

Share this post


Link to post
4 hours ago, Rollo62 said:

Wow, Ok you have a bigger task to do then.

I am lucky not to need to keep on old Delphi, I try always move further to the latest Rx version.

Anyway, your project sounds like a task for big GIT scenario with clever CI.

Good luck.

Rollo,

 

  GIT and whatever CI is are beyond my skillset. I'm just a slogger working through it, one app at a time. Problem is, it's one app every six hours at the rate I'm going. And year end is 80 days away. Seventy if I want to try things out first. Which doesn't leave much time for basketball on the TV and things like eating, sleeping and going to see the doctors. Sigh.

 

  Deadline pressure is good, if it doesn't kill you first. [G]

 

  GM

Share this post


Link to post
4 hours ago, Fr0sT.Brutal said:

Ok, now it's more clear. I see no reasons why it shouldn't work if you'll have one DPR and thousands of forms. Just rename them in namespace manner and use in umbrella DPR, no auto-create is needed. Just do Application.CreateForm in your umbrella main form's menu onClick handlers. However, you'll have to ensure your under-umbrella apps contain nothing in their DPR but default App.Init/CreateForm/Run.

Frost,

 

  The renaming is not quite as easy as I thought it might be. I wanted to go in and edit the DFM and the PAS files and replace FrmMain with FrmMainActivityReportToolset in the copy I had made of FMain.Pas renamed to FMainActivityReportToolset.Pas/DFM. Then, I used the search and replace to find frmMain with the longer monicker. But I'm getting a lot of errors when calling up the form from the umbrella. The DPR file in the sub-folder might be involved somehow. So I'm going to work on that theory for the next few hours and then cutaway to watch the Clippers Raptors game. Back at it come midnight.

 

  Thanks for suggestion. GM

Share this post


Link to post

Have you considered to call several EXE files in the umbrella app ?

They seem not be related much yet, so that could be a way to be faster.

Edited by Rollo62
  • Like 1

Share this post


Link to post
11 hours ago, Gary Mugford said:

  The renaming is not quite as easy as I thought it might be. I wanted to go in and edit the DFM and the PAS files and replace FrmMain with FrmMainActivityReportToolset in the copy I had made of FMain.Pas renamed to FMainActivityReportToolset.Pas/DFM. Then, I used the search and replace to find frmMain with the longer monicker. But I'm getting a lot of errors when calling up the form from the umbrella. The DPR file in the sub-folder might be involved somehow. So I'm going to work on that theory for the next few hours and then cutaway to watch the Clippers Raptors game. Back at it come midnight.

The easiest way to rename form DFM/PAS files is using IDE's "Save As" action, and renaming the form itself is best with changing the name of the form component from designer.

Share this post


Link to post
5 hours ago, Rollo62 said:

Have you considered to call several EXE files in the umbrella app ?

They seem not be related much yet, so that could be a way to be faster.

This is actually a really good idea. Call the .EXE's and dock their window into your application, like a new tabsheet. And until the clients are happy, you can work on the refactoring 🙂

Share this post


Link to post
9 hours ago, aehimself said:

This is actually a really good idea. Call the .EXE's and dock their window into your application, like a new tabsheet. And until the clients are happy, you can work on the refactoring 🙂

Actually it's a really bad idea. Cross process window parenting relationships just don't work out. Don't even think about it. 

Share this post


Link to post
16 minutes ago, David Heffernan said:

Actually it's a really bad idea. Cross process window parenting relationships just don't work out. Don't even think about it. 

I respectfully disagree. I had issues with focus and modals not being true modals but otherwise it's working pretty all right. I have to admit that I docked quite simple applications (like PUTTY) until now, though.

Share this post


Link to post

Actually, I'm unfortunately going to have to agree with Mr. Heffernan. The end goal is a working umbrella process, it's true. BUT the end goal is also to have one cohesive program to run against Delphi Parser with a capped licence of 1M lines of code. So, I'm trying to pare down everything, no duplication, no sub-folders. Just code to update via Parser so as to change Database backbones. The idea of calling exe's would BE a solution if there was no next step. But there is. At that, they have the umbrella already ... the Windows desktop, in the form of LOTS of icons. Well, not lots. Each user gets icons for sub-applications that are pertinent to that user. 

 

My problem right now is that I have apparently wasted my time collecting all the code into one great-big folder and 74 sub-folders with subfolders and subfolders etc. That action was premature. I was hoping to speed things along, but the opposite has happened. The issue is that in ADDING units that weren't in the settings as search path entries LIKE my own home-grown utility libraries, they hard-coded PART of the paths in the DPR's uses unit. Now, I'm DISCARDING the DPR, but there's something in the DNA of the program that when I bring it up to rename the form, planning to save this copy of the form PAS file into a different name, something goes astray every time. It MIGHT have something to do with AJC Active Backup maybe getting confused given the file name no longer tracks back to the last version in it's database. Don't think so, but I'm throwing mud against the wall looking for a hidden message. Not everything, Maybe one out of four or five, but then the time with that one takes FOREVER to get done. Also, any mini-app with sub-forms takes two or three times the time of a single form, but that's to be expected. 

 

As I asked in the OP, I was looking for pitfalls. And I've found them. For future readers similarly run afoul of their own design, I hope reading this in advance of trying what I'm doing will help, although the better advice is ... Don't Screw It Up In The First Place.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×