2017-08-22 9 views
3

Je crée un Simple Direct2D Application. Malheureusement, il donne une exception non gérée. La fonction où il a lieu:Direct2D: Exception non gérée dans le commutateur 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)); 
    } 
} 

Et l'extrait de code d'appel OnResize() est:

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

L'exception dit: exception non gérée à 0x00007FF6BE402CCA dans Simple Direct2D application.exe: 0xC000041D : Une exception non gérée a été rencontrée lors d'un rappel utilisateur. eu lieu

capture d'écran d'exception:

the pic of exception

Dès que je commence à déboguer, le programme, il donne le exception.I même copié le mot du programme par mot des site.As Je suis nouveau Pour le monde de DirectX, je ne sais rien de l'exception. Que devrais-je faire?

Répondre

1

Étant donné que vous obtenez une exception dans un point où vous ne faites rien d'autre que de lire une variable membre, la seule raison que je peux penser est que votre pointeur this est garbage. Bien qu'il soit courant que les gestionnaires de messages fenêtre soient appelés avant l'appel de SetWindowLong, auquel cas la valeur renvoyée par GetWindowLong est null, vous vérifiez (correctement) que ce n'est pas le cas, ce que confirme votre capture d'écran (ainsi que le fait que c'est de la poubelle). Les options possibles restantes sont que ce que vous passez à SetWindowLong n'est pas un pointeur vers un objet DemoApp valide, ou qu'il l'a déjà été mais que l'objet n'est plus valide lorsque le message est reçu. Alors, comme une réponse à votre question, vous devez vérifier que

  1. la valeur que vous passez à SetWindowLong est vraiment un pointeur valide à un DemoApp
  2. le DemoApp dont le pointeur que vous passez est dans le tas ou une variable globale , pas une variable locale qui peut aller hors de portée pendant toute la durée de la fenêtre
  3. vous ne supprimez pas votre objet DemoApp, si elle est tas alloué, au cours de la durée de vie de votre fenêtre

en outre, vous utilisent explicitement la version Unicode de GetWindowLongPtr, qui est également utilisée dans l'exemple original (sans explication pourquoi). Vérifiez les paramètres de votre projet que vous compilez une application Unicode.

2

J'ai compilé cet exemple. Il fonctionne dans les versions 32 bits, se bloque dans les versions 64 bits.

L'erreur est dans l'exemple de code de Microsoft et n'est pas liée à Direct2D.

Ils transmettent this en SetWindowLongPtr, en combinaison avec la macro PtrToUlong pour la conversion de type. Dans les versions 64 bits, this est de 8 octets de long, SetWindowLongPtr accepte également 8 octets, cependant PtrToUlong macro convertit en unsigned long qui est seulement 4 octets. Donc PtrToUlong macro tombe plus haut 4 octets de this pointeur, et l'application échoue spectaculairement.

Vous pouvez corriger en remplaçant PtrToUlong(pDemoApp) avec (LONG_PTR)pDemoApp

post-scriptumJe pense que la cause première est, MS prétend très difficile Win32 plate-forme est obsolète, pousse les développeurs à UWP à la place. C'est pourquoi dans leurs exemples DirectX et Direct2D, ils n'utilisent pas leur propre ATL, car c'est une bibliothèque de bureau uniquement. L'utilisation d'ATL simplifierait considérablement ces exemples: CComPtr pour les pointeurs d'interface, CWindowImpl pour la création de fenêtres et la gestion des messages, et bien plus encore.

Mise à jour: here's a better sample.

+0

Merci, ça a marché !!! – Dhannanjai

+0

que dois-je faire si je veux apprendre Direct2d? Devrais-je aller apprendre l'UWP? Ou s'en tenir à rester à la base? Je demande parce que j'ai essayé la programmation UWP et son ahurissant ... – Dhannanjai

+1

@Dannanjai Cela dépend de ce que vous allez faire avec D2D. BTW, voir la mise à jour. – Soonts