2

我想为 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?

4

0 回答 0