Holdem Manager に似た PokerStars 用の HUD を作成したい:
Visual Studio と C# 言語、および Windows 7 64 ビットを使用しています。HUD には、いくつかの情報を含むいくつかのボックスが表示されます。ボックスはドラッグ可能で半透明でなければならず、ユーザーは不透明度を設定できます。これらのボックスのいずれかにマウスを合わせると、追加情報が表示されます。HUD が表示される PokerStars ウィンドウを制御することはできません。つまり、Visual Studio で編集することはできません。これを達成する方法と、これを行うための最良の方法についてアドバイスが必要です。
私の最初の試みは、PInvoke を介して SetParent 関数を使用して Windows フォームを使用することでしたが、透過性が機能しません。
私の HUD は、取り付けられているウィンドウに追加情報を提供する必要がある半透明のボックスのセットです。問題は、別のアプリケーションのフォーム内にある場合、hud 要素を半透明にできないことです。私の hud 要素は、Form クラスから継承したボックスです。それはボーダーレス フォーム (BorderStyle が "None" に設定され、不透明度 100%) であり、内部にいくつかの色付きのラベルがあり、作成時にコードは追加されていません。そのため、Form1 というメイン フォーム クラスと、Form1 内に表示する hud 要素である HUDBox という別のフォーム クラスがあります。どちらも Form クラスから継承します。HUDBox オブジェクトの不透明度を 100% 未満に設定すると、HUDBox オブジェクトは Form1 オブジェクト内に表示されません。私もTransparencyKeyを使ってみましたが、PInvoke を介して 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 のコードは単純な自動生成フォームであるため、関係ありません。このプログラムは、メイン フォーム内に hud 要素の 4 つのコピーを追加します。私の Form1 クラスはテスト用です。外部の PokerStars ウィンドウに置き換えられます。Form1 の子として設定されていないため、SetParent 関数を使用しない場合、hud ボックスの不透明度は正常に機能します。
また、HUDBox フォームの代わりに UserControl を使用しようとしました: 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 要素を PokerStars ウィンドウの子にして正しい透明度を維持する方法はありますか?
おそらく GDI を使用して、この HUD を作成する別の方法はありますか?