3

我正在为游戏添加插件,但我希望它作为游戏窗口客户区域的覆盖层。

基本上当我开始添加时,我希望它显示在游戏之上。问题是,如果您最小化或移动窗口,我希望表单能够坚持下去。

任何人都知道无需挂钩直接绘制就可以做到这一点的任何事情吗?

谢谢。

4

1 回答 1

5

这是一个简单的方法来做到这一点。首先,您需要在表单的 using 语句中使用这一行:

using System.Runtime.InteropServices;

接下来,将这些声明添加到您的表单中:

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int X;
    public int Y;
    public int Width;
    public int Height;
}

[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

[DllImport("user32.dll", SetLastError = true)]
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

接下来,将表单的 TopMost 属性设置为 True。最后,在表单中添加一个 Timer 控件,将其 Interval 属性设置为 250,并将其 Enabled 属性设置为 True,并将以下代码放入它的 Tick 事件中:

IntPtr hWnd = FindWindow(null, "Whatever is in the game's title bar");
RECT rect;
GetWindowRect(hWnd, out rect);
if (rect.X == -32000)
{
    // the game is minimized
    this.WindowState = FormWindowState.Minimized;
}
else
{
    this.WindowState = FormWindowState.Normal;
    this.Location = new Point(rect.X + 10, rect.Y + 10);
}

如果游戏未最小化,此代码将使您的表单位于游戏的表单之上,或者如果游戏被最小化,它也会最小化您的表单。要更改应用程序的相对位置,只需更改最后一行中的“+ 10”值。

更复杂的方法将涉及挂钩窗口消息以确定游戏窗体何时最小化或移动或更改大小,但这种轮询方法将更简单地完成几乎相同的事情。

最后一点:如果 FindWindow 没有找到具有该标题的窗口,它将返回 0,因此您可以在游戏关闭时使用它来关闭您自己的应用程序。

于 2009-09-18T03:39:12.330 回答