Search code examples
c++c++buildervcl

c++ with vcl: closing secondary form does not end process


I'm still learning c++ with vcl forms so forgive me if what I'm asking turns out to be simpler than it seems. For reference, I'm using c++ builder 10.1 berlin in a Windows environment.

I have a program with two forms (lets call them "MainForm" and "BackupForm"). I am accepting user input in MainForm, then when the user clicks a particular button ("DoSomething") that action sets a few variables then calls BackupForm->Show(); then MainForm->Hide(); to switch over to the second form which does more things.

The issue I'm having is this: if a user clicks the "X" in the upper right that normally closes a program, it only closes the BackupForm and does not end the process. If I did the same action on the MainForm it ends the process.

I looked around and either wasn't asking the right question or no-one but me has this issue, or perhaps hiding/showing to switch forms isn't the right way to go about it, but my overall question is this:

TLDR: Is there a way/method/etc. to detect the "close window" button being pressed on a secondary form and subsequently close the application, ending it's process without having to kill it in task manager?

If there's a better way to be switching forms that I'm unaware of, I wouldn't mind suggestions towards that end as well.

Also, if needed, I can post more of the code but I wasn't sure what would actually be helpful. Below is some of what I have:

Main (Function? Application?) Pre-generated by my IDE:

#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//------------------------------------------------------------------------
USEFORM("BackupFormCode.cpp", BackupForm);
USEFORM("UserBackupProgram.cpp", MainForm);
//----------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        Application->Initialize();
        Application->MainFormOnTaskBar = true;
        Application->CreateForm(__classid(TMainForm), &MainForm);
        Application->CreateForm(__classid(TBackupForm), &BackupForm);
        Application->Run();
    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
    catch (...)
    {
        try
        {
            throw Exception("");
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
    return 0;
}

Button "DoSomething" Pressed in "MainForm":

void __fastcall TMainForm::ExecuteCopyClick(TObject *Sender)
{
    //Setting variables.... 
    //Then:
    BackupForm->Show();
    MainForm->Hide(); 
}

Solution

  • Your MainForm is being auto-created first, so it gets set as the Application->MainForm.

    When the Application->MainForm is actually closed, it calls Application->Terminate(), causing Application->Run() to exit, thus allowing WinMain() to exit and the process to terminate.

    When you show BackupForm, you are merely hiding the MainForm, not closing it. So Application->Terminate() is not getting called.

    If you want the process to terminate when BackupForm is closed, you need to either:

    • Close() the Application->MainForm:

      void __fastcall TBackupForm::FormClose(TObject *Sender, TCloseAction &Action)
      {
          Application->MainForm->Close(); 
      }
      

      Or:

      void __fastcall TMainForm::ExecuteCopyClick(TObject *Sender)
      {
          //Setting variables.... 
          //Then:
          Hide(); 
          BackupForm->ShowModal();
          Close();
      }
      
    • just call Application->Terminate() directly:

      void __fastcall TBackupForm::FormClose(TObject *Sender, TCloseAction &Action)
      {
          Application->Terminate(); 
      }