我有一些代码如下:
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。但是,这在所有情况下都不可行。我也搜索了很多答案,到目前为止还没找到。
感谢您的期待!
答案 0 :(得分:3)
有办法解决这个问题,但它们有点难看。
最干净的设计通常是避免与标准Win32惯用语冲突的设计,在Win32的世界中,模态对话框返回ID
值中的一个,以指示用户在解除它们时单击的按钮(仅喜欢消息框)。严格来说,它是nResult
参数传递给用于关闭模态对话框的EndDialog
函数。
我建议不要尝试使用其他含义重载此返回值。试图这样做只会让你遇到麻烦(例如,你可能还还没有注意到返回值为-1意味着对话框的创建失败了。)
而是在对话框类中定义一个额外的成员变量,并使用它来报告您的其他信息。成功后,您将从对话框中返回IDOK
。如果失败(任何类型的失败),请返回IDCANCEL
之类的内容。然后,您在OnButtonClick
内的代码会检查返回值是IDOK
还是IDCANCEL
。如果它是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.
}
}
}
答案 1 :(得分: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上面所说,我认为你最好从DoModal
返回一个标准错误代码,例如IDABORT
,而不是像这样重载返回代码。然后只需要一个用户必须显式检索的二级错误代码,这是您自己的“内部”错误代码。
答案 2 :(得分:0)
您可以使用枚举而不是宏定义的返回码,使用命名空间以避免名称冲突。看看Boost Error Handling Policy:
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