2011-11-05 88 views
1

我想在Windows窗體主機控件的WPF窗口內託管XNA遊戲。我有一個奇怪的問題,當我運行遊戲時會創建一個「幻影」窗口。它是在第一次調用遊戲的Update方法退出時創建的。在WPF內部託管XNA - 奇怪的「幽靈」窗口問題

這裏是更新代碼,從一個新的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); 
    } 

創建後,我從最後一個大括號步驟在最底層的窗口。 (是的,怪異要把它不是在base.Update之後卻在該}後)

我有一個Windows窗體主機正如我已經說過,用下面的代碼:

相關的XAML是在這裏(我已經得到了明顯的形式命名空間等進行設置,所以沒有必要在這裏貼):

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

和代碼隱藏:

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

在觀衆是我的邯E類(從XNA),具有:

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; 
    } 

這種技術是從一個博客帖子我前幾天發現(我不能再現在發現,它是完全一樣的方式 - 用這個帖子是舊的,並沒有我遇到的問題的例外)。

問題是,我建立並運行,但隨着我的「正常」窗口,有一個幻影窗口創建。在我的主窗口中,XNA呈現正確。但幻影窗口(窗口標題是我的程序集名稱),沒有任何內容,不可調整大小,光標不在其內部顯示,並且它在主窗口中起作用,因爲當我最小化該窗口時,我的主窗口停止渲染XNA內容,直到我將幻像窗口最小化。我的程序不會退出,直到我關閉兩個窗口。 (如果我只關閉幻像,我猜主窗口會停止渲染我的XNA內容)。我試着用App.Current.Windows迭代我的應用程序窗口,我所有的主窗口都列在那裏,這就是爲什麼我將這個半響應窗口稱爲「幻影」窗口的原因。它在WPF中的對象模型中不可見。

當我寫「XNA WPF幻影窗口」,第一我有是這樣的:WPF: How to determine the origin of a phantom window?

所以我去,並試圖窺探。但是Snoop可能也依賴於迭代,並且在那裏也沒有看到任何額外的窗口。我使用十字拖動功能(將光標拖動到屏幕上,Snoop會告訴它屬於哪個進程和窗口),並且Snoop會告訴Phantom Window實際上是我的MainWindow。但據Snoop稱,我的MainWindow也是同一個窗口。所以這個幻影與我的MainWindow實例有些密切相關(或者可能是一個「孩子」?),但我需要一種方法來關閉它(或者至少隱藏它)。

任何想法?

回答

1

WPF中嵌入XNA的兩個好方法,我知道的是在這個崗位(一個在後本身所描述的,另一種是在第一個鏈接在帖子中描述):

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

兩者都有代碼示例,我以前使用過WriteableBitmap版本,結果良好。 (我創建的開發工具不需要顯示大於384x384的任何東西,因此FPS是可以接受的;如果您需要具有大緩衝區的高FPS(例如800x600,720p等),您一定要使用HwndHost方法)。

我建議嘗試這兩個最適合您的需求之一。當您嘗試使用XNA創建的窗口時,XNA的WinForms窗口期望成爲頂級窗口。我嘗試過解決諸如過去發佈的內容,但從未超越幻影窗口問題。

+0

好,必須有一些方法來糾正地方。我希望儘可能保持高水平,而且我已經有了工作,只需要一個幻影窗口,所以應該有一個「單行代碼」來關閉它。 –

0

而且僅僅是一個解決辦法,我認爲我們仍堅持這一是最好的,直到新的東西進來..

經過進一步調查,我發現了幻影窗口是「窗口句柄」的遊戲實例,並且遊戲需要繼續運行。它可以作爲遊戲的窗口句柄來訪問,並且可以通過它創建(實際上引用已有的)表單。該遊戲還阻止了WPF TextBox等對象的輸入機制,並且通過派生TextBox類並手動覆蓋OnKeyDown(我們得到了一個非常不便(但現在適用於我)的解決方法)在文本輸入。)和手動引發TextInput事件。有點哈克,但工作。用這個形式,我可以將不透明度設置爲零,並將它移動到不在中間的某個位置,並且它將停留在那裏。

但是我的解決方案只是一個拙劣的解決方法,Mike的解決方案肯定更好,所以如果您正在閱讀本文並且剛剛開始一個像這樣的新項目,請按照他的回答。

1

我寫這個並且剛剛完成它,也許這可以幫助你。我爲XNA < - > WPF兼容性的明確目的而寫了它。也就是說,讓XNA能夠在WPF的特定控件中呈現。給它一個鏡頭:

https://xnaml.codeplex.com/

+0

看起來很酷。我會給它一個鏡頭,如果我喜歡它,我會用它來製作我的地圖編輯器。 –

+1

很高興知道。享受它,如果有東西應該加入它,讓我知道。 – 2012-04-26 21:22:08