2011-11-05 1 views
1

J'essaie d'héberger un jeu XNA dans une fenêtre WPF en utilisant le contrôle de l'hôte Windows Forms. J'ai un problème étrange qu'une fenêtre "Phantom" est créée quand je cours le jeu. Il est créé exactement au premier appel aux sorties de la méthode Update du jeu.Hébergement de XNA dans WPF - Problème étrange de fenêtre "Phantom"

Voici le code de mise à jour, la valeur par défaut un d'un nouveau projet XNA:

protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 

     // TODO: Add your update logic here 

     base.Update(gameTime); 
    } 

La fenêtre est créée après je l'étape de la dernière accolade au bas. (. Oui, bizarre d'avoir ce pas base.Update mais après la } après)

J'ai un Windows Forms hôte comme je l'ai dit, avec le code ci-dessous:

Le XAML est pertinent ici (J'ai évidemment eu les formulaires espace de noms, etc. mis en place donc pas besoin de coller ici):

<WindowsFormsHost Margin="12" Name="windowsFormsHost1"> 
    <forms:Panel x:Name="p"></forms:Panel> 
</WindowsFormsHost> 

et codebehind:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     Viewer v = new Viewer(p.Handle); 
     v.Run(); 
    } 

où le spectateur est mon Gam classe e (à partir XNA), avec:

public Viewer(IntPtr handle) 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
     panelHandle = handle; 
     graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings); 
    } 

    void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e) 
    { 
     e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = panelHandle; 
    } 

Cette technique est d'un billet de blog que j'ai trouvé il y a quelques jours (je ne trouve pas encore maintenant, il est de la même manière - avec l'exception que le poste était vieux et n'a pas le problème que j'ai).

Le problème est que je compile et exécute, mais avec ma fenêtre "normale", il y a une fenêtre fantôme créée. Dans ma fenêtre principale, XNA s'affiche correctement. Mais la fenêtre fantôme (le titre de la fenêtre est le nom de mon assembly), n'a rien dedans, n'est pas redimensionnable, le curseur ne rend pas à l'intérieur, et agit comme la fenêtre principale dans le sens où je minimise cette fenêtre , ma fenêtre principale arrête de rendre le contenu XNA jusqu'à ce que je dé-minimise cette fenêtre fantôme. Mon programme ne quitte pas jusqu'à ce que je ferme les deux fenêtres. (Si je ferme seulement le fantôme, ma fenêtre principale, comme vous le devinez, arrête de rendre mon contenu XNA). J'ai essayé d'itérer sur mes fenêtres d'application, avec 'App.Current.Windows', et tout ce que j'ai est ma fenêtre principale listée ici, c'est pourquoi j'appelle cette fenêtre semi-sensible la fenêtre "fantôme". Il n'est pas visible dans mon modèle objet dans WPF.

Quand j'ai écrit « fenêtre fantôme XNA WPF », le premier que j'ai été ceci: WPF: How to determine the origin of a phantom window?

Alors je suis allé et essayé Snoop. Mais Snoop repose probablement aussi sur l'itération Windows, et il n'y voit pas non plus de fenêtre supplémentaire. J'utilise la fonction crosshair-drag (vous faites glisser le curseur sur l'écran et Snoop indique à quel processus et à quelle fenêtre il appartient), et Snoop dit que la fenêtre Phantom est en fait ma MainWindow. Mais ma MainWindow est aussi la même fenêtre, selon Snoop. Donc, ce fantôme est un peu plus proche (ou peut-être un "enfant"?) De mon instance MainWindow, mais j'ai besoin d'un moyen de le fermer (ou au moins de le cacher).

Des idées?

Répondre

1

Les deux bonnes façons d'intégrer XNA dans WPF que je connais sont dans ce poste (on est décrit dans le poste lui-même, l'autre est décrit dans le premier lien dans le message):

http://blogs.msdn.com/b/nicgrave/archive/2011/03/25/wpf-hosting-for-xna-game-studio-4-0.aspx

Les deux ont des exemples de code et j'ai déjà utilisé la version WriteableBitmap avec de bons résultats. (Je créais un outil de développement qui n'avait pas besoin de montrer quelque chose de plus grand que 384x384 donc FPS était acceptable, si vous avez besoin d'un FPS élevé avec un grand tampon arrière (par exemple 800x600, 720p, etc.) Méthode HwndHost).

Je vous recommande d'essayer celui de ces deux qui correspond le mieux à vos besoins. Lorsque vous essayez d'utiliser la fenêtre créée par XNA, la fenêtre WinForms de XNA s'attend à être une fenêtre de niveau supérieur. J'ai essayé de déconner avec des solutions telles que ce que vous avez posté dans le passé mais je n'ai jamais dépassé le problème de la fenêtre fantôme.

+0

Eh bien, il doit y avoir un moyen de corriger quelque part. Je veux rester aussi haut que possible tout en faisant cela, et j'ai déjà le truc qui marche, juste avec une fenêtre fantôme, donc il devrait y avoir un "code de ligne" pour l'éteindre quelque part .. –

0

En plus d'être juste une solution, je pense que nous sommes coincés avec ce qui est le meilleur jusqu'à ce que quelque chose de nouveau arrive ..

Après une enquête plus poussée, je l'ai découvert que la fenêtre fantôme est la « poignée de fenêtre » de l'instance de jeu, et il est nécessaire pour que le jeu continue de fonctionner. Il pourrait être consulté en tant que handle de fenêtre du jeu, et en créant (en fait en faisant référence à un existant) un formulaire de celui-ci. Le jeu a également empêché les mécanismes d'entrée des objets tels que WPF TextBox, et j'ai obtenu une solution de contournement très gênante (mais fonctionne pour moi maintenant) en dérivant la classe TextBox et en remplaçant le OnKeyDown manuellement (il a attrapé le même mais bizarrement ne mettait pas dans la saisie de texte.) et levant un événement TextInput manuellement. Un peu hacky, mais ça marche. Et avec la forme, je peux juste mettre l'opacité à zéro et la déplacer quelque part pas au milieu, et elle restera là.

Mais ma solution est juste une solution de contournement hacky et la solution de Mike est définitivement meilleure, donc si vous lisez ceci et juste pour commencer un nouveau projet comme ceux-ci, suivez sa réponse.

1

J'ai écrit ceci et je l'ai terminé tout à l'heure, peut-être que cela peut vous aider. Je l'ai écrit dans le but exprès de XNA < -> Compatibilité WPF; c'est-à-dire, avoir XNA capable de rendre à l'intérieur d'un contrôle spécifique sur WPF. Donnez-lui un coup de feu:

https://xnaml.codeplex.com/

+0

semble plutôt cool . Je vais essayer et si je l'aime je vais l'utiliser pour faire mon éditeur de carte. –

+1

Bon à savoir. Appréciez-le, et s'il y a des choses qui devraient être collées sur lui, lemme savoir. –