"The Parameter Is Incorrect" MFC异常

"The Parameter Is Incorrect" MFC exception

这是本机 C++。不涉及 .NET 框架。

我试图找出当 CListBox 获取无效参数时抛出的异常。事实证明 MFC 经常使用此异常,但我无法确定抛出的实际异常类型。我在 catch (int, const char , std:) 上尝试了很多不同的类型,但是除了 catch(...) 之外唯一捕获它的是 (const void * ).查看内存结构,我仍然不知道实际抛出的是什么。 有谁知道它是什么或如何确定它抛出的是什么?

这是一个示例 MFC 应用程序。 ListBox 是一个 CListBox。该应用程序只不过是 VS 自动构建的默认基于 DialogBox 的 MFC 应用程序。唯一的变化是我添加了一个列表框和您在下面的“确定”按钮处理程序中看到的代码。

void CMFCApplication1Dlg::OnBnClickedOk()
{
    try
    {
        CString Value;
        ListBox.GetText( -1, Value );
        Value = "none";
    }
    catch ( CException & exception )
    {
            exception.Delete();
    }
    catch ( const void * e )
    {
    }
    catch (...)
    {
    }

    CDialogEx::OnOK();
}

答案是:

catch ( const COleException * e )

我使用的是 catch ( const COleException & e ),正如所有教科书所说的那样。好吧。

具体可以在 Exception Handling in MFC, and Exceptions: Catching and Deleting Exceptions 找到详细信息。

为了解释为什么会出现异常,看起来当您使用 CListBox::GetText()CString 版本时,如果传递的索引无效,它会抛出 E_INVALIDARG 异常。跟踪 MFC 代码有点麻烦,但 CListBox::GetText() 看起来像:

void CListBox::GetText(int nIndex, CString& rString) const
{
        ASSERT(::IsWindow(m_hWnd));
        GetText(nIndex, rString.GetBufferSetLength(GetTextLen(nIndex)));
        rString.ReleaseBuffer();
}

CListBox::GetTextLen(-1) 将 return LB_ERR-1。如果您遵循 CString::GetBufferSetLength() 的代码,您最终会得到 CString::SetLength():

void SetLength(_In_ int nLength)
{
      ATLASSERT( nLength >= 0 );
      ATLASSERT( nLength <= GetData()->nAllocLength );

      if( nLength < 0 || nLength > GetData()->nAllocLength)
             AtlThrow(E_INVALIDARG);

      GetData()->nDataLength = nLength;
      m_pszData[nLength] = 0;
}

with nLength == -1 因此例外。

请注意,此 无效参数异常 现在可以通过调用 UpdateAllViews() 发生。我通过 MFC libraries 深入跟踪代码。它来自 macro,它只为发布版本生成抛出。

因为它很深,它可以从其他几个函数中发生。