如何正确使用wxID_OK和wxID_CANCEL?

How to correctly use wxID_OK and wxID_CANCEL?

有一个图表 window,右键单击它会显示一个弹出菜单,然后在选择后会显示一个 window:

void CChart::Series_OnPopupMenu(wxCommandEvent& evt)
{
    int evtID = evt.GetId();


if (m_dlgManageSeriesData)
    return;


if(evtID==ID_ADDNEW) 
{
    m_dlgManageSeriesData=new dlgManageSeriesData(this);

    m_dlgManageSeriesData->Bind(wxEVT_CLOSE_WINDOW, &CChart::OnDlgManageSeriesDataClose, this);


    m_dlgManageSeriesData->Show();
}

为了能够跟踪显示的 window 是否关闭:

void CChart::OnDlgManageSeriesDataClose(wxCloseEvent & evt)
{
    m_dlgManageSeriesData->Unbind(wxEVT_CLOSE_WINDOW, &CChart::OnDlgManageSeriesDataClose, this);

    m_dlgManageSeriesData = nullptr;

    evt.Skip();
}

window,即dlgManageSeriesData,有两个按钮:

m_BtnOK = new wxButton(this, wxID_OK, "OK"); 

m_BtnCancel = new wxButton(this, wxID_CANCEL, "Cancel");

例如,当点击取消按钮时,它应该关闭 window:

void dlgManageSeriesData::OnBtnCancelClick(wxCommandEvent & event)
{
    Close();
}

不同场景下发生的事情很少:

1) 如果我不尝试用 dlgManageSeriesData::OnBtnCancelClick 手动关闭 window,则保留 wxID_CANCEL 并单击 Cancel 按钮按预期将其关闭 wxDialog但是,似乎以这种方式关闭 window 不会生成 wxEVT_CLOSE_WINDOW,因为从未调用 CChart::OnDlgManageSeriesDataClose

2) 如果我尝试用 Close() 关闭 window 同时保持 wxID_CANCEL,window 永远不会关闭.

3) 如果我更改按钮的 ID 并将取消按钮声明为 m_BtnCancel = new wxButton(this, wxID_ANY, "Cancel"); 一切都按预期工作,这样取消按钮会关闭 window 和 CChart::OnDlgManageSeriesDataClose 被调用。 OK 按钮也遵循类似的原理。


也许我误解了一些概念,但有几个问题:

1) wxWidgets 的事件处理系统是否以不同方式处理这些 ID(wxID_OK 或 wxID_CANCEL),从而防止 window从关闭开始?

2) 如果在 window关闭?

我在 Windows 10 和 VS 2017 上使用 wxWidgets 3.1.3。

啊啊啊,wxWidgets ...好时光:)

按钮构造器中的 wxID_* 只允许您在弹出窗口中实现事件处理程序 window:

BEGIN_EVENT_TABLE(FooClass, wxDialog)
    EVT_BUTTON(wxID_OK, FooClass::OnButtonOkClick)
END_EVENT_TABLE()

您可以使用 ID 关闭模态对话框:

void FooClass::OnButtonOkClick(wxCommandEvent& event)
{

   EndModal(wxID_OK);

   event.Skip(false);
}

然后调用者接收此值作为 return 对话框 ShowModal 调用的值:

...
FooClass dialog(this);
int result = dialog.ShowModal();
if (result == wxID_OK)
{
    ...
}

如果您的弹出窗口是 wxWindow 类型,我认为没有这种机制可以 return 一个值。考虑派生自 wxDialog。

wxWidgets 默认在对话框中专门显示 wxID_OKwxID_CANCEL,并为标准行为提供内置逻辑。

但是,如果您根本没有像您所说的那样使用 wxDialog,那么这根本不重要,尽管这并不完全清楚。而且,事实上,如果您不想以模态方式显示它,就没有真正的理由使用 wxDialog.

如果您真的只是创建一个普通的 wxFrame 并从其中一个按钮的事件处理程序中调用 Close(),这应该独立于您为其使用的 ID。