我想为PokerStars创建类似于Holdem Manager的HUD:
我使用的是Visual Studio和C#语言,以及Windows 7 64位。 HUD会显示一些包含一些信息的方框。这些盒子必须是可拖动和半透明的,用户可以设置它们的不透明度。当鼠标悬停其中一个框时,会显示其他信息。我无法控制将拥有HUD的PokerStars扑克窗口,即我无法在Visual Studio中编辑它。 我需要一些关于如何实现这一点的建议,以及实现这一目标的最佳方法。
我的第一次尝试是通过PInvoke使用带有SetParent函数的Windows窗体,但透明度不起作用:
我的HUD只是一组半透明的盒子,必须为它们所附着的窗口提供额外的信息。问题是,当我的hud元素在另一个应用程序的表单中时,我无法使其变为半透明。我的hud元素是一个继承自Form类的框。它只是一个无边框形式(BorderStyle设置为“None”,100%不透明度),里面有一些彩色标签,创建它时没有添加任何代码。所以,我有一个名为Form1的主表单类和另一个名为HUDBox的表单类,它是我想在Form1中显示的hud元素。两者都继承自Form类。 如果我将HUDBox对象的不透明度设置为小于100%的任何值,则HUDBox对象将不会显示在Form1对象中。我也尝试通过PInvoke使用TransparencyKey,SetWindowLong和SetLayeredWindowAttributes,但它使一切都透明,而不仅仅是HUDBox对象。这是代码:
的Program.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,透明度不起作用:
我也试过使用以下功能的组合,但没有任何效果,透明度应用于整个窗口instad中的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元素PokerStars窗口的孩子保持正确的透明度?
是否有另一种创建此HUD的方法,可能是使用GDI?