5

我有一些代码如下所示:

void MyClass::OnButtonClick()
{
    int retVal = SomeDialog.DoModal();
    if(retVal == MYCLASS_ERROR)
    {
        MessageBox("Error"...blah ...blah);
    }
    else if(retVal == IDOK)   // IDOK is returned on clicking the 'OK' button
    {
        MessageBox("All is well"...blah ...blah);
    }
}
  • SomeDialog只显示一个进度条。出现任何错误时,进度条会通过调用自动关闭EndDialog(MYCLASS_ERROR)。只有在成功完成后,用户才能在此处单击“确定”。
  • MYCLASS_ERROR是一个enum包含各种返回类型和状态的值。

我发现在点击确定时SomeDialog,仍然显示错误信息!我挖得更深了,发现MYCLASS_ERROR= IDOK= 1。

所以我的问题是,我应该如何定义所有这些返回状态,使其不会与任何其他实现的状态发生冲突?这意味着,我的函数应该返回任何其他函数(或尽可能少的其他函数)不返回的值。

我想修改我的设计,使所有函数只返回 TRUE 或 FALSE。但是,这并非在所有情况下都是可行的。我也搜索了很多答案,但到目前为止还没有找到任何答案。

感谢您的关注!

4

3 回答 3

3

有一些方法可以解决这个问题,但它们有点难看。

最简洁的设计通常是避免与标准 Win32 习惯用法发生冲突的设计,在 Win32 的世界中,模式对话框返回ID值之一以指示用户在关闭它们时单击的按钮(就像消息框一样)。严格来说,它nResult是传递给EndDialog用于关闭模态对话框的函数的参数。

我建议不要试图用额外的意义重载这个返回值。尝试这样做只会给您带来麻烦(例如,您可能没有注意到返回值 -1 意味着创建对话框失败)。


相反,在您的对话框类中定义一个附加成员变量并使用它来报告您的附加信息。成功后,您将从IDOK对话框返回。在失败(任何类型的失败)时,返回类似IDCANCEL. 然后,您的代码OnButtonClick将检查返回值是否为IDOKIDCANCEL。如果是IDCANCEL,那么您需要查询添加到对话框中的成员变量的值以获取更多信息。

希望这是有道理的。如果不是,也许这个代码示例将(假设这m_errStatus是您添加到子类的成员变量CDialog):

void MyClass::OnButtonClick()
{
    if (SomeDialog.DoModal() == IDOK)
    {
        // Success!
        // The OK button was clicked, so IDOK was returned.
        MessageBox("All is well"...blah ...blah);
    }
    else
    {
        // Failure!
        // Some error occurred, so IDCANCEL (or any other value) was returned.
        // Determine what to do now, based on additional information that the
        // dialog set upon failure.
        switch (SomeDialog.m_errStatus)
        {
            case MYCLASS_ERROR_1:
                MessageBox("Error 1 occurred.");
                break;
            case MYCLASS_ERROR_2:
                MessageBox("Error 2 occurred.");
                break;
            // etc.
        }
    }
}
于 2013-03-12T11:50:38.973 回答
1

您可以简单地将自定义错误代码定义为不与 Windows 返回值“冲突”。当然,你不知道微软什么时候会添加新的返回值,所以这总是有点古怪。

你可以尝试这样的事情:

enum MYERR
{
    MYERR_FIRST_ERROR   = 0x0F000000, /* large and unlikely to be used */
    MYERR_SECOND_ERROR,
    MYERR_THIRD_ERROR,
    /* and so on */
};

但是,正如 Cody Gray 上面所说,我认为你最好从 中返回标准错误代码DoModalIDABORT而不是像那样重载返回代码。然后只需要有一个用户必须明确检索的辅助错误代码,这是您自己的“内部”错误代码。

于 2013-03-12T18:14:27.300 回答
0

您可以使用枚举而不是宏定义的返回代码,并使用命名空间以避免名称冲突。查看Boost 错误处理策略

namespace boost { namespace math { namespace policies {

enum error_policy_type
{
   throw_on_error = 0, // throw an exception.
   errno_on_error = 1, // set ::errno & return 0, NaN, infinity or best guess.
   ignore_error = 2, // return 0, NaN, infinity or best guess.
   user_error = 3  // call a user-defined error handler.
};

}}} // namespaces
于 2013-03-12T11:34:23.703 回答