使用C#为PokerStars创建HUD

时间:2012-11-03 12:53:35

标签: c# winforms hud

我想为PokerStars创建类似于Holdem Manager的HUD:

Screenshot

我使用的是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,透明度不起作用:

Screenshot

我也试过使用以下功能的组合,但没有任何效果,透明度应用于整个窗口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?

0 个答案:

没有答案