【问题标题】:How to close a docked VCL form in C++Builder如何在 C++Builder 中关闭停靠的 VCL 表单
【发布时间】:2019-01-01 21:20:27
【问题描述】:

我正在将 C++Builder 与 VCL 表单应用程序一起使用。我正在尝试关闭停靠在 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;
  }
}

【问题讨论】:

    标签: c++builder vcl


    【解决方案1】:

    您需要调用Form-&gt;Close() 而不是Form-&gt;OnCloseQuerty(),但保持事件代码不变(因为您希望关闭确认对话框)

    1. Form-&gt;OnCloseQuerty()

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

    2. Form-&gt;Close()

      这会强制Form 关闭。但首先 VCL 将调用 Form-&gt;OnCloseQuerty() 并根据其结果忽略关闭或继续它。

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

    另一种方法是使用new,delete 动态创建和删除表单。无论Form-&gt;OnCloseQuery() 结果如何,删除表单都会强制关闭Form

    我有时会结合这两种方法...并在OnCloseQuery()和App销毁之前设置Visible=falseCanClose=falsedelete都是动态Forms...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 2018-02-08
      • 2012-12-02
      相关资源
      最近更新 更多