Direct2D:WM_RESIZE开关案例中的未处理异常

时间:2017-08-22 17:11:19

标签: c++ directx msdn unhandled-exception direct2d

我正在创建Simple Direct2D Application。不幸的是它给了 一个未处理的例外。它正在发生的功能:

    void DemoApp::OnResize(UINT width, UINT height)
{
    if (m_pRenderTarget) <----|****The exception occurs here.....****
    {
        // Note: This method can fail, but it's okay to ignore the
        // error here, because the error will be returned again
        // the next time EndDraw is called.
        m_pRenderTarget->Resize(D2D1::SizeU(width, height));
    }
}

调用OnResize()的代码片段为:

DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hwnd,
                GWLP_USERDATA
            )));

        bool wasHandled = false;

        if (pDemoApp)
        {
            switch (message)
            {
            case WM_SIZE:
            {
                UINT width = LOWORD(lParam);
                UINT height = HIWORD(lParam);
                pDemoApp->OnResize(width, height);
            }
            result = 0;
            wasHandled = true;
            break;
/*rest of switch case*/
       }

例外说: Simple Direct2D application.exe中0x00007FF6BE402CCA处的未处理异常:0xC000041D:在用户回调期间遇到未处理的异常。发生

Exception截图:

the pic of exception

一旦我开始调试程序,就会给出异常。我甚至从网站上逐字复制程序。由于我是DirectX的新手,我对这个异常一无所知。我该怎么办?

2 个答案:

答案 0 :(得分:4)

我编译了那个样本。它适用于32位版本,在64位版本中崩溃。

错误在Microsoft的示例代码中,与Direct2D无关。

他们将this传递给SetWindowLongPtr,并与PtrToUlong宏结合使用以进行类型转换。在64位版本中,this长度为8个字节,SetWindowLongPtr也接受8个字节,但PtrToUlong宏转换为unsigned long,只有4个字节。因此PtrToUlong宏从this指针下降了4个字节,并且应用程序失败了。

您可以将PtrToUlong( pDemoApp )替换为(LONG_PTR)pDemoApp

来解决问题

P.S。我认为根本原因是,MS假装非常努力的Win32平台已经过时,而是将开发人员推向了UWP。这就是为什么在他们的DirectX和Direct2D示例中,他们不使用自己的ATL,因为它是仅限桌面的库。使用ATL可以大大简化这些示例:CComPtr用于接口指针,CWindowImpl用于Windows创建和消息处理等等。

更新:here's a better sample

答案 1 :(得分:1)

由于你在除了读取成员变量之外什么都没做的时候得到一个异常,我能想到的唯一可能的原因就是你的this指针是垃圾。虽然在调用SetWindowLong之前调用窗口消息处理程序是很常见的,但在这种情况下,GetWindowLong返回的值为null,您(正确地)检查它是不是,并且这是由您的屏幕截图确认的(如以及它的垃圾这一事实。剩下的可能选项是传递给SetWindowLong的内容不是指向有效DemoApp对象的指针,或者它曾经是,但是当收到消息时该对象不再有效。因此,作为您问题的答案,您应该检查

  1. 传递给SetWindowLong的值确实是指向DemoApp的有效指针
  2. 您传递的指针位于堆中的DemoApp或全局变量,而不是在窗口生命周期内可能超出范围的局部变量
  3. 如果你的DemoApp对象在窗口的生命周期内被分配了堆,那么你就不会删除它。
  4. 此外,您明确使用了Unicode版本的GetWindowLongPtr,它也在原始示例中使用(没有解释原因)。检查您正在编译Unicode应用程序的项目设置。

相关问题