如何在 C++Builder 中关闭停靠的 VCL 窗体
How to close a docked VCL form in C++Builder
我正在将 C++Builder 与 VCL 表单应用程序一起使用。我正在尝试关闭停靠在 TPageControl 上的 VCL 窗体。我的关闭按钮位于程序主窗体的工具栏上。我执行此操作的方法是以下三个步骤:我可以单步执行所有这些代码,但是当它完成时没有任何反应,表单不会关闭。我在这里做错了什么?
- 单击停靠表单时,我将表单名称保存到全局变量。
- 单击 CloseButton 时,我使用 Screen->Forms[] 遍历所有表单并找到正确的表单。然后我调用事件表单->OnCloseQuery.
- 在 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;
}
}
您需要调用 Form->Close()
而不是 Form->OnCloseQuerty()
但保留事件代码(因为您需要关闭确认对话框)
Form->OnCloseQuerty()
由 VCL 调用 你不应该自己调用它!!!它有不同的含义,它不会强制 Form
关闭,但如果 CanClose
设置为 false
,它可以拒绝 Close
事件。
Form->Close()
这会强制 Form
关闭。但首先 VCL 将调用 Form->OnCloseQuerty()
并根据其结果忽略关闭或继续执行它。
还有另一种选择来做你想做的事。如果您只想隐藏您的表单,您也可以将其 Visible
属性 设置为 false。当想再次使用它时,只需使用 Show()
甚至 ShowModal()
或再次将其 Visible
设置为 True
(这取决于您的应用程序是否为 MDI 与否).
另一种方法是使用 new,delete
动态创建和删除表单。无论 Form->OnCloseQuery()
结果如何,删除表单都会强制 Form
关闭。
我有时会结合这两种方法...并在OnCloseQuery()
和应用程序销毁delete
之前设置Visible=false
和CanClose=false
所有动态Forms
...
我正在将 C++Builder 与 VCL 表单应用程序一起使用。我正在尝试关闭停靠在 TPageControl 上的 VCL 窗体。我的关闭按钮位于程序主窗体的工具栏上。我执行此操作的方法是以下三个步骤:我可以单步执行所有这些代码,但是当它完成时没有任何反应,表单不会关闭。我在这里做错了什么?
- 单击停靠表单时,我将表单名称保存到全局变量。
- 单击 CloseButton 时,我使用 Screen->Forms[] 遍历所有表单并找到正确的表单。然后我调用事件表单->OnCloseQuery.
- 在 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;
}
}
您需要调用 Form->Close()
而不是 Form->OnCloseQuerty()
但保留事件代码(因为您需要关闭确认对话框)
Form->OnCloseQuerty()
由 VCL 调用 你不应该自己调用它!!!它有不同的含义,它不会强制
Form
关闭,但如果CanClose
设置为false
,它可以拒绝Close
事件。Form->Close()
这会强制
Form
关闭。但首先 VCL 将调用Form->OnCloseQuerty()
并根据其结果忽略关闭或继续执行它。
还有另一种选择来做你想做的事。如果您只想隐藏您的表单,您也可以将其 Visible
属性 设置为 false。当想再次使用它时,只需使用 Show()
甚至 ShowModal()
或再次将其 Visible
设置为 True
(这取决于您的应用程序是否为 MDI 与否).
另一种方法是使用 new,delete
动态创建和删除表单。无论 Form->OnCloseQuery()
结果如何,删除表单都会强制 Form
关闭。
我有时会结合这两种方法...并在OnCloseQuery()
和应用程序销毁delete
之前设置Visible=false
和CanClose=false
所有动态Forms
...