2017-08-22 19 views
3

Simple Direct2D Applicationを作成しています。残念ながら、 に未処理の例外を与えています。それが行われている機能:Direct2D:未処理の例外WM_RESIZEのスイッチケースで

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*/ 
     } 

例外は言う:シンプルDirect2Dのapplication.exeで0x00007FF6BE402CCAで 未処理の例外:0xC000041Dを:ユーザーのコールバック中に未処理の例外が発生しました。発生した

例外スクリーンショット:

the pic of exception

できるだけ早く私は、デバッグを開始として、プログラムは、それがexception.Iも新品ですsite.Asから単語によってプログラムワードをコピーできますDirectXの世界には、例外についてはわかりません。私は何をすべきか?

答えて

1

メンバー変数を読むだけで何もしていないという点で例外が発生しているので、考えられる唯一の理由はこのポインタがゴミであることだけです。 SetWindowLongが呼び出される前にGetWindowLongから返された値がnullの場合は、ウィンドウメッセージハンドラが呼び出されるのが一般的ですが、そうでないことを(正しく)チェックします。これはスクリーンショットでも確認されますそれはゴミだという事実)。可能なオプションは、SetWindowLongに渡すものが有効なDemoAppオブジェクトへのポインタではないか、以前にあったものの、メッセージが受信されたときにオブジェクトが有効でなくなったことです。だから、あなたの質問への答えとして、あなたはSetWindowLong関数に渡す

  1. 値は本当にそのポインタを渡すのDemoAppは、ヒープやグローバル変数であるのDemoApp
  2. への有効なポインタであることを確認する必要がありますそれはあなたが、あなたの窓の寿命も

時に、ヒープ割り当てられている場合、ウィンドウ

  • の寿命の間に範囲の外に出ることができないローカル変数は、あなたは、あなたのDemoAppオブジェクトを削除しないでくださいGetWindowLongPtrのUnicode版を明示的に使用しています。これは、元の例では(理由はありません)。 Unicodeアプリケーションをコンパイルするプロジェクト設定を確認します。

  • 2

    私はそのサンプルをコンパイルしました。これは32ビットビルドで動作し、64ビットビルドでクラッシュします。

    エラーはMicrosoftのサンプルコードです.Direct2Dとは無関係です。

    これらは、タイプ変換のためにPtrToUlongマクロと組み合わせて、SetWindowLongPtrthisを渡します。 64ビットビルドでは、thisは8バイト長ですが、SetWindowLongPtrも8バイトを受け入れますが、PtrToUlongマクロはunsigned longに4バイトしか変換されません。だからPtrToUlongマクロはthisポインターから上位4バイトを落とし、アプリはすばらしく失敗します。

    あなたは(LONG_PTR)pDemoApp

    P.S.でPtrToUlong(pDemoApp)を交換することによって修正することができます私は根本的な原因は、MSは非常に難しいWin32プラットフォームは、時代遅れだと思うが、代わりにUWPに開発者をプッシュすると思います。 DirectXとDirect2Dのサンプルでは、​​デスクトップ専用のライブラリであるため、独自のATLを使用していません。 ATLを使用すると、インターフェイスポインタ用のCComPtr、ウィンドウの作成とメッセージ処理用のCWindowImpl、その他多くのサンプルが大幅に簡略化されます。

    更新:here's a better sample

    +0

    ありがとうございました! – Dhannanjai

    +0

    Direct2dを習得したい場合はどうすればよいですか?私はUWPを学ぶべきでしょうか?または、基本的に残っているところにこだわる?私はUWPプログラミングとその心が揺れ動いているので、私は尋ねています... – Dhannanjai

    +1

    @DhannanjaiそれはあなたがD2Dで何をするつもりかによって異なります。ところで、更新を参照してください。 – Soonts