How to close a docked VCL form in C++Builder












1















I am using C++Builder with a VCL Forms Application. I am trying to close a VCL Form that is docked on a TPageControl. My Close button is on a toolbar on the program's main form. My approach to do this is the three steps below: I can step through all this code but when it is done nothing happens, the form is not closed. What am I doing wrong here?




  1. When a docked form is clicked I save the form name to global variable.

  2. When the CloseButton is clicked, I use Screen->Forms to loop through all forms and find the correct form. Then I call the event form->OnCloseQuery.

  3. In the FormCloseQuery event I call the FormClose event.


.



void __fastcall TAboutForm::FormClick(TObject *Sender)
{
MainForm1->LastSelectedFormName = AboutForm->Name;
}

void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
{ //Identify The Form to Delete by Name
bool q=true;
UnicodeString FormName="";

int cnt = Screen->FormCount;
for(int i=0; i<cnt; i++ )
{
TForm* form = Screen->Forms[i];
FormName = form->Name;
if(CompareText(FormName, LastSelectedFormName)==0){
form->OnCloseQuery(form, q); //close this form
break;
}
}
}

void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

if(Code ==IDYES){
TCloseAction Action = caFree;
FormClose(Sender, Action);
}
}

void __fastcall TAboutForm::FormClose(TObject *Sender, TCloseAction &Action)
{
Action = caFree;
}


Below is an edit after reading the answer from Spektre



Calling form->OnClose(form, MyAction); will not trigger the FormCloseQuery event. I have to call FormCloseQuery manually. The only way I could get the docked form to close is by adding, delete Sender; to the FormCloseQuery.



This does not look like a correct solution. I am very surprised Embarcadero does not have a recommended way to close a docked form. This seems like a very common action. I read the doc-wiki and can not find any solution to close a docked form.



void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
{ //Identify The Form to Delete by Name
bool MyCanClose=true;
UnicodeString FormName="";
TCloseAction MyAction = caFree;
int cnt = Screen->FormCount;

for(int i=0; i<cnt; i++ )
{
TForm* form = Screen->Forms[i];
FormName = form->Name;
if(CompareText(FormName, LastSelectedFormName)==0){
// form->OnClose(form, MyAction);
form->OnCloseQuery(form, MyCanClose);
break;
}
}
}

void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

if(Code ==IDYES){
delete Sender;
Sender = NULL;
}
}









share|improve this question





























    1















    I am using C++Builder with a VCL Forms Application. I am trying to close a VCL Form that is docked on a TPageControl. My Close button is on a toolbar on the program's main form. My approach to do this is the three steps below: I can step through all this code but when it is done nothing happens, the form is not closed. What am I doing wrong here?




    1. When a docked form is clicked I save the form name to global variable.

    2. When the CloseButton is clicked, I use Screen->Forms to loop through all forms and find the correct form. Then I call the event form->OnCloseQuery.

    3. In the FormCloseQuery event I call the FormClose event.


    .



    void __fastcall TAboutForm::FormClick(TObject *Sender)
    {
    MainForm1->LastSelectedFormName = AboutForm->Name;
    }

    void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
    { //Identify The Form to Delete by Name
    bool q=true;
    UnicodeString FormName="";

    int cnt = Screen->FormCount;
    for(int i=0; i<cnt; i++ )
    {
    TForm* form = Screen->Forms[i];
    FormName = form->Name;
    if(CompareText(FormName, LastSelectedFormName)==0){
    form->OnCloseQuery(form, q); //close this form
    break;
    }
    }
    }

    void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
    {
    int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

    if(Code ==IDYES){
    TCloseAction Action = caFree;
    FormClose(Sender, Action);
    }
    }

    void __fastcall TAboutForm::FormClose(TObject *Sender, TCloseAction &Action)
    {
    Action = caFree;
    }


    Below is an edit after reading the answer from Spektre



    Calling form->OnClose(form, MyAction); will not trigger the FormCloseQuery event. I have to call FormCloseQuery manually. The only way I could get the docked form to close is by adding, delete Sender; to the FormCloseQuery.



    This does not look like a correct solution. I am very surprised Embarcadero does not have a recommended way to close a docked form. This seems like a very common action. I read the doc-wiki and can not find any solution to close a docked form.



    void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
    { //Identify The Form to Delete by Name
    bool MyCanClose=true;
    UnicodeString FormName="";
    TCloseAction MyAction = caFree;
    int cnt = Screen->FormCount;

    for(int i=0; i<cnt; i++ )
    {
    TForm* form = Screen->Forms[i];
    FormName = form->Name;
    if(CompareText(FormName, LastSelectedFormName)==0){
    // form->OnClose(form, MyAction);
    form->OnCloseQuery(form, MyCanClose);
    break;
    }
    }
    }

    void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
    {
    int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

    if(Code ==IDYES){
    delete Sender;
    Sender = NULL;
    }
    }









    share|improve this question



























      1












      1








      1








      I am using C++Builder with a VCL Forms Application. I am trying to close a VCL Form that is docked on a TPageControl. My Close button is on a toolbar on the program's main form. My approach to do this is the three steps below: I can step through all this code but when it is done nothing happens, the form is not closed. What am I doing wrong here?




      1. When a docked form is clicked I save the form name to global variable.

      2. When the CloseButton is clicked, I use Screen->Forms to loop through all forms and find the correct form. Then I call the event form->OnCloseQuery.

      3. In the FormCloseQuery event I call the FormClose event.


      .



      void __fastcall TAboutForm::FormClick(TObject *Sender)
      {
      MainForm1->LastSelectedFormName = AboutForm->Name;
      }

      void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
      { //Identify The Form to Delete by Name
      bool q=true;
      UnicodeString FormName="";

      int cnt = Screen->FormCount;
      for(int i=0; i<cnt; i++ )
      {
      TForm* form = Screen->Forms[i];
      FormName = form->Name;
      if(CompareText(FormName, LastSelectedFormName)==0){
      form->OnCloseQuery(form, q); //close this form
      break;
      }
      }
      }

      void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
      {
      int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

      if(Code ==IDYES){
      TCloseAction Action = caFree;
      FormClose(Sender, Action);
      }
      }

      void __fastcall TAboutForm::FormClose(TObject *Sender, TCloseAction &Action)
      {
      Action = caFree;
      }


      Below is an edit after reading the answer from Spektre



      Calling form->OnClose(form, MyAction); will not trigger the FormCloseQuery event. I have to call FormCloseQuery manually. The only way I could get the docked form to close is by adding, delete Sender; to the FormCloseQuery.



      This does not look like a correct solution. I am very surprised Embarcadero does not have a recommended way to close a docked form. This seems like a very common action. I read the doc-wiki and can not find any solution to close a docked form.



      void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
      { //Identify The Form to Delete by Name
      bool MyCanClose=true;
      UnicodeString FormName="";
      TCloseAction MyAction = caFree;
      int cnt = Screen->FormCount;

      for(int i=0; i<cnt; i++ )
      {
      TForm* form = Screen->Forms[i];
      FormName = form->Name;
      if(CompareText(FormName, LastSelectedFormName)==0){
      // form->OnClose(form, MyAction);
      form->OnCloseQuery(form, MyCanClose);
      break;
      }
      }
      }

      void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
      {
      int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

      if(Code ==IDYES){
      delete Sender;
      Sender = NULL;
      }
      }









      share|improve this question
















      I am using C++Builder with a VCL Forms Application. I am trying to close a VCL Form that is docked on a TPageControl. My Close button is on a toolbar on the program's main form. My approach to do this is the three steps below: I can step through all this code but when it is done nothing happens, the form is not closed. What am I doing wrong here?




      1. When a docked form is clicked I save the form name to global variable.

      2. When the CloseButton is clicked, I use Screen->Forms to loop through all forms and find the correct form. Then I call the event form->OnCloseQuery.

      3. In the FormCloseQuery event I call the FormClose event.


      .



      void __fastcall TAboutForm::FormClick(TObject *Sender)
      {
      MainForm1->LastSelectedFormName = AboutForm->Name;
      }

      void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
      { //Identify The Form to Delete by Name
      bool q=true;
      UnicodeString FormName="";

      int cnt = Screen->FormCount;
      for(int i=0; i<cnt; i++ )
      {
      TForm* form = Screen->Forms[i];
      FormName = form->Name;
      if(CompareText(FormName, LastSelectedFormName)==0){
      form->OnCloseQuery(form, q); //close this form
      break;
      }
      }
      }

      void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
      {
      int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

      if(Code ==IDYES){
      TCloseAction Action = caFree;
      FormClose(Sender, Action);
      }
      }

      void __fastcall TAboutForm::FormClose(TObject *Sender, TCloseAction &Action)
      {
      Action = caFree;
      }


      Below is an edit after reading the answer from Spektre



      Calling form->OnClose(form, MyAction); will not trigger the FormCloseQuery event. I have to call FormCloseQuery manually. The only way I could get the docked form to close is by adding, delete Sender; to the FormCloseQuery.



      This does not look like a correct solution. I am very surprised Embarcadero does not have a recommended way to close a docked form. This seems like a very common action. I read the doc-wiki and can not find any solution to close a docked form.



      void __fastcall TMainForm1::CloseButtonClick(TObject *Sender)
      { //Identify The Form to Delete by Name
      bool MyCanClose=true;
      UnicodeString FormName="";
      TCloseAction MyAction = caFree;
      int cnt = Screen->FormCount;

      for(int i=0; i<cnt; i++ )
      {
      TForm* form = Screen->Forms[i];
      FormName = form->Name;
      if(CompareText(FormName, LastSelectedFormName)==0){
      // form->OnClose(form, MyAction);
      form->OnCloseQuery(form, MyCanClose);
      break;
      }
      }
      }

      void __fastcall TAboutForm::FormCloseQuery(TObject *Sender, bool &CanClose)
      {
      int Code = Application->MessageBox(L"Close Form", L"Close Form", MB_YESNO|MB_ICONINFORMATION);

      if(Code ==IDYES){
      delete Sender;
      Sender = NULL;
      }
      }






      c++builder vcl






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 3 at 23:11







      homebase

















      asked Jan 1 at 21:20









      homebasehomebase

      3301210




      3301210
























          1 Answer
          1






          active

          oldest

          votes


















          4














          You need to call Form->Close() instead of the Form->OnCloseQuerty() but leave the event code as is (as you want the close confirmation dialog)





          1. Form->OnCloseQuerty()



            is called by VCL you should not call it on yourself !!! It has different meaning it does not force the Form to close but it can reject the Close event if CanClose is set to false.




          2. Form->Close()



            This one force the Form to Close. But first the VCL will call the Form->OnCloseQuerty() and according to its result it either ignore the Close or proceed with it.




          There are also another alternatives to do what you want. In case you just want to hide your Form you can also set its Visible property to false instead. And when want to use it again just use Show() or even ShowModal() or set its Visible to True again (it depends on if your App is MDI or not).



          Another way is to create and delete the Form dynamically using new,delete. The delete of the form is forcing the Form to close regardless of Form->OnCloseQuery() result.



          I sometimes combine these two methods ... And set the Visible=false and CanClose=false in OnCloseQuery() and before the App destruction delete all dynamical Forms ...






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999024%2fhow-to-close-a-docked-vcl-form-in-cbuilder%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            4














            You need to call Form->Close() instead of the Form->OnCloseQuerty() but leave the event code as is (as you want the close confirmation dialog)





            1. Form->OnCloseQuerty()



              is called by VCL you should not call it on yourself !!! It has different meaning it does not force the Form to close but it can reject the Close event if CanClose is set to false.




            2. Form->Close()



              This one force the Form to Close. But first the VCL will call the Form->OnCloseQuerty() and according to its result it either ignore the Close or proceed with it.




            There are also another alternatives to do what you want. In case you just want to hide your Form you can also set its Visible property to false instead. And when want to use it again just use Show() or even ShowModal() or set its Visible to True again (it depends on if your App is MDI or not).



            Another way is to create and delete the Form dynamically using new,delete. The delete of the form is forcing the Form to close regardless of Form->OnCloseQuery() result.



            I sometimes combine these two methods ... And set the Visible=false and CanClose=false in OnCloseQuery() and before the App destruction delete all dynamical Forms ...






            share|improve this answer






























              4














              You need to call Form->Close() instead of the Form->OnCloseQuerty() but leave the event code as is (as you want the close confirmation dialog)





              1. Form->OnCloseQuerty()



                is called by VCL you should not call it on yourself !!! It has different meaning it does not force the Form to close but it can reject the Close event if CanClose is set to false.




              2. Form->Close()



                This one force the Form to Close. But first the VCL will call the Form->OnCloseQuerty() and according to its result it either ignore the Close or proceed with it.




              There are also another alternatives to do what you want. In case you just want to hide your Form you can also set its Visible property to false instead. And when want to use it again just use Show() or even ShowModal() or set its Visible to True again (it depends on if your App is MDI or not).



              Another way is to create and delete the Form dynamically using new,delete. The delete of the form is forcing the Form to close regardless of Form->OnCloseQuery() result.



              I sometimes combine these two methods ... And set the Visible=false and CanClose=false in OnCloseQuery() and before the App destruction delete all dynamical Forms ...






              share|improve this answer




























                4












                4








                4







                You need to call Form->Close() instead of the Form->OnCloseQuerty() but leave the event code as is (as you want the close confirmation dialog)





                1. Form->OnCloseQuerty()



                  is called by VCL you should not call it on yourself !!! It has different meaning it does not force the Form to close but it can reject the Close event if CanClose is set to false.




                2. Form->Close()



                  This one force the Form to Close. But first the VCL will call the Form->OnCloseQuerty() and according to its result it either ignore the Close or proceed with it.




                There are also another alternatives to do what you want. In case you just want to hide your Form you can also set its Visible property to false instead. And when want to use it again just use Show() or even ShowModal() or set its Visible to True again (it depends on if your App is MDI or not).



                Another way is to create and delete the Form dynamically using new,delete. The delete of the form is forcing the Form to close regardless of Form->OnCloseQuery() result.



                I sometimes combine these two methods ... And set the Visible=false and CanClose=false in OnCloseQuery() and before the App destruction delete all dynamical Forms ...






                share|improve this answer















                You need to call Form->Close() instead of the Form->OnCloseQuerty() but leave the event code as is (as you want the close confirmation dialog)





                1. Form->OnCloseQuerty()



                  is called by VCL you should not call it on yourself !!! It has different meaning it does not force the Form to close but it can reject the Close event if CanClose is set to false.




                2. Form->Close()



                  This one force the Form to Close. But first the VCL will call the Form->OnCloseQuerty() and according to its result it either ignore the Close or proceed with it.




                There are also another alternatives to do what you want. In case you just want to hide your Form you can also set its Visible property to false instead. And when want to use it again just use Show() or even ShowModal() or set its Visible to True again (it depends on if your App is MDI or not).



                Another way is to create and delete the Form dynamically using new,delete. The delete of the form is forcing the Form to close regardless of Form->OnCloseQuery() result.



                I sometimes combine these two methods ... And set the Visible=false and CanClose=false in OnCloseQuery() and before the App destruction delete all dynamical Forms ...







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Jan 2 at 9:50

























                answered Jan 2 at 9:45









                SpektreSpektre

                30k647219




                30k647219
































                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53999024%2fhow-to-close-a-docked-vcl-form-in-cbuilder%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

                    Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

                    A Topological Invariant for $pi_3(U(n))$