我想为 PokerStars 创建一个类似于 Holdem Manager 的 HUD:
我正在使用 Visual Studio 和 C# 语言,以及 Windows 7 64 位。HUD 将显示一些带有一些信息的框。这些框必须是可拖动的和半透明的,并且用户可以设置它们的不透明度。当鼠标悬停在其中一个框上时,会显示附加信息。我无法控制拥有 HUD 的 PokerStars 窗口,即我无法在 Visual Studio 中对其进行编辑。我需要一些关于如何实现这一目标的建议,以及做到这一点的最佳方法是什么。
我的第一次尝试是通过 PInvoke 使用带有 SetParent 功能的 Windows 窗体,但透明度不起作用:
我的 HUD 只是一组半透明的盒子,它们必须为它们所连接的窗口提供额外的信息。问题是当我的 hud 元素位于另一个应用程序的表单中时,我无法使它成为半透明的。我的 hud 元素是一个继承自 Form 类的框。它只是一个无边框的表单(BorderStyle 设置为“无”,100% 不透明度),里面有一些彩色标签,创建时没有添加代码。所以,我有一个名为 Form1 的主窗体类和另一个名为 HUDBox 的窗体类,这是我想在 Form1 中显示的 hud 元素。两者都继承自 Form 类。如果我将 HUDBox 对象的不透明度设置为小于 100%,HUDBox 对象就不会显示在 Form1 对象内。我也尝试过使用 TransparencyKey,SetWindowLong 和 SetLayeredWindowAttributes 通过 PInvoke 但它使所有内容都透明,而不仅仅是 HUDBox 对象。这是代码:
程序.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
namespace MyHUD
{
public static class Program
{
public static Form1 mainForm;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
mainForm = new Form1();
HUD psHUD = new HUD();
Application.Run(mainForm);
}
}
}
HUD.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Drawing;
namespace MyHUD
{
class HUD
{
private static int HOW_MANY_HUDBOXES = 4;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private List<HUDBox> hudBoxes = new List<HUDBox>(HOW_MANY_HUDBOXES);
public HUD()
{
initHudBoxes();
}
private void initHudBoxes()
{
for (int hb = 0; hb < HOW_MANY_HUDBOXES; hb++)
{
HUDBox newHudBox = new HUDBox();
hudBoxes.Add(newHudBox);
//SetParent(newHudBox.Handle, Program.mainForm.Handle);
newHudBox.Show();
}
UserControl1 control = new UserControl1();
SetParent(control.Handle, Program.mainForm.Handle);
control.Show();
}
}
}
HUDBox.cs 和 Form1.cs 的代码不相关,因为它们是简单的自动生成的表单。这个程序在主窗体中添加了 4 个我的 hud 元素的副本。我的 Form1 类仅用于测试,它将被外部 PokerStars 窗口所取代。当我不使用 SetParent 函数时,Opacity 对我的 hud 框效果很好,因为它们没有设置为 Form1 的子项。
我还尝试使用 UserControl 而不是我的 HUDBox 表单:UserControl1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MyHUD
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.BackColor = Color.FromArgb(127, 0, 0, 255);
}
private void UserControl1_Load(object sender, EventArgs e)
{
}
}
}
我已经使用 VisualStudio 手动将此 UserControl1 添加到 Form1 中,并且它以正确的不透明度显示正常,但随后我通过 SetParent 添加了另一个 UserControl1 并且透明度不起作用:
我也尝试使用以下功能的组合,但没有任何效果,透明度应用于整个窗口,而不是其中的 hud 元素:
[DllImport("user32.dll")]
static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);
[DllImport("user32.dll", SetLastError=true)]
static extern int GetWindowLong(IntPtr hWnd, int nIndex);
public const int GWL_EXSTYLE = -20;
public const int WS_EX_LAYERED = 0x80000;
public const int LWA_ALPHA = 0x2;
public const int LWA_COLORKEY = 0x1;
//set the window style to alpha appearance
private void setWindowOpacity(IntPtr handle, byte opacity)
{
SetLayeredWindowAttributes(handle, 0, opacity, LWA_ALPHA);
}
private void setWindowLayered(IntPtr handle)
{
SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle, GWL_EXSTYLE) ^ WS_EX_LAYERED);
}
有没有办法让我的扑克之星窗口的 hud 元素保持正确的透明度?
有没有另一种方法来创建这个HUD,也许是使用GDI?