如何在C ++ Builder中关闭停靠的VCL表单

时间:2019-01-01 21:20:27

标签: c++builder vcl

我正在将C ++ Builder与VCL Forms应用程序一起使用。我正在尝试关闭停靠在TPageControl上的VCL表单。我的关闭按钮位于程序主窗体的工具栏上。我执行此操作的方法是以下三个步骤:我可以逐步执行所有这些代码,但是完成后什么都没有发生,因此窗体没有关闭。我在这里做错了什么?

  1. 单击停靠的表单时,我将表单名称保存到全局变量。
  2. 单击CloseButton时,我使用Screen-> Forms []遍历所有表单并找到正确的表单。然后,我将事件表单称为-> OnCloseQuery。
  3. 在FormCloseQuery事件中,我称为FormClose事件。

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;
}

下面是阅读Spektre的答案后的修改内容

调用表单-> OnClose(form,MyAction);不会触发FormCloseQuery事件。我必须手动调用FormCloseQuery。我可以关闭停靠表单的唯一方法是添加,删除发件人。到FormCloseQuery。

这似乎不是正确的解决方案。我很惊讶Embarcadero没有建议的方法来关闭停靠表单。这似乎是很常见的动作。我阅读了doc-wiki,找不到任何解决方案来关闭停靠的表单。

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;
  }
}

1 个答案:

答案 0 :(得分:4)

您需要调用Form->Close()而不是Form->OnCloseQuerty(),但请保持事件代码不变(如需要关闭确认对话框)

  1. Form->OnCloseQuerty()

    VCL 调用,您不应该自己调用它!它具有不同的含义,它不会强制Form关闭,但是如果Close设置为CanClose,它可以拒绝false事件。

  2. Form->Close()

    这迫使Form关闭。但是首先 VCL 将调用Form->OnCloseQuerty(),并根据其结果忽略关闭或继续执行。

还有其他选择可以做您想要的。如果您只想隐藏表单,则也可以将其Visible属性设置为false。而要再次使用它时,只需使用Show()甚至是ShowModal()或再次将其Visible设置为True(这取决于您的应用程序是否为 MDI 还是不)。

另一种方法是使用new,delete动态创建和删除表单。表单的删除将强制Form关闭,而不考虑Form->OnCloseQuery()结果。

我有时会结合使用这两种方法...并在Visible=false中以及在应用程序销毁CanClose=false之前将OnCloseQuery()delete都设置为动态Forms。 ..