【发布时间】:2011-11-05 08:12:48
【问题描述】:
我正在尝试使用 Windows 窗体主机控件在 WPF 窗口中托管 XNA 游戏。我有一个奇怪的问题,当我运行游戏时会创建一个“幻影”窗口。它是在第一次调用游戏的Update 方法退出时创建的。
这是更新代码,来自新 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 在这里(我显然已经设置了 Forms 命名空间等,因此无需在此处粘贴):
<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();
}
Viewer 是我的 Game 类(来自 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 可能还依赖于 Windows 迭代,并且它也看不到任何额外的窗口。我使用十字准线拖动功能(您在屏幕上拖动光标,Snoop 告诉它属于哪个进程和窗口),Snoop 告诉 Phantom Window 实际上是我的 MainWindow。但根据 Snoop 的说法,我的 MainWindow 也是同一个窗口。所以这个幻象与我的 MainWindow 实例有点密切相关(或者可能是“孩子”?),但我需要一种方法来关闭它(或者至少隐藏它)。
有什么想法吗?
【问题讨论】: