作成したフォームを半透明にするのであればOpacityプロパティを使えばできます。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); Opacity = 0.5; // Opacity = 1.0 完全に不透明 // Opacity = 0.0 完全に透明 } } |
では他のウィンドウを半透明にすることはできるのでしょうか? API関数を使えば可能です。
1 2 |
[DllImport("user32.dll", SetLastError = true)] private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); |
ただこの関数をそのまま実行してもうまくいきません。この関数を使うためには拡張ウィンドウスタイルにWS_EX_LAYEREDが追加されていなければなりません。そこで最初に拡張ウィンドウスタイルにWS_EX_LAYEREDを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); } [DllImport("user32.dll", EntryPoint = "GetWindowLong", SetLastError = true)] private static extern IntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", SetLastError = true)] private static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex); [DllImport("user32.dll", EntryPoint = "SetWindowLong", SetLastError = true)] private static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", SetLastError = true)] private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll", SetLastError = true)] private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); private const int GWL_EXSTYLE = -20; private const int WS_EX_LAYERED = 0x00080000; private IntPtr GetWindowLongPtr(IntPtr hWnd, int nIndex) { if(IntPtr.Size == 8) return GetWindowLongPtr64(hWnd, nIndex); else return GetWindowLongPtr32(hWnd, nIndex); } private IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong) { if(IntPtr.Size == 8) return SetWindowLongPtr64(hWnd, nIndex, dwNewLong); else return SetWindowLongPtr32(hWnd, nIndex, dwNewLong); } bool AddExStyle(IntPtr handle, int style) { int winFlags = (int)GetWindowLongPtr(handle, GWL_EXSTYLE); if(winFlags == 0) { int error = Marshal.GetLastWin32Error(); if(error != 0) { MessageBox.Show("GetWindowLongPtrが失敗"); return false; } } if((winFlags & WS_EX_LAYERED) == 0) { winFlags |= WS_EX_LAYERED; SetWindowLongPtr(handle, GWL_EXSTYLE, new IntPtr(winFlags)); } return true; } // ウィンドウを半透明にする falseが返されたときは失敗 public bool SetOpacity(IntPtr handle, byte alpha) { // WS_EX_LAYEREDがないなら追加する if(!AddExStyle(handle, WS_EX_LAYERED)) return false; if(!SetLayeredWindowAttributes(handle, 0, alpha, 0x2)) { MessageBox.Show("SetLayeredWindowAttributesが失敗"); return false; } return true; } } |
これでSetOpacityメソッドを実行すればフォームを半透明にすることができます。
1 2 3 4 5 6 7 |
public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { SetOpacity(this.Handle, 128); } } |
では他のアプリケーションのウィンドウを半透明にすることはできるのでしょうか?
Targetと書かれている部分(label1)を半透明にしたいウィンドウにドラッグすると、ドロップされたウィンドウを半透明にすることができます。
label1でマウスがクリックされたらマウスキャプチャします。マウスキャプチャされているのでフォームの外側でもマウスの動きを追跡することができます。
そしてマウスが離されたらその座標を調べます。その座標のウィンドウハンドルを調べてSetOpacityメソッドを実行します。
他のアプリケーションのウィンドウを半透明にした場合、元に戻すための手段を用意しなければなりません。そこでウィンドウを半透明にしたらそのウィンドウハンドルを保存しておき、必要なときに元に戻せるようにしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); // 0にしてしまうと完全に透明になるので32より小さい値は設定できないようにする // 最大値は255 numericUpDown1.Maximum = 255; numericUpDown1.Minimum = 32; numericUpDown1.Value = 255; } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } // 座標からウィンドウハンドルを求める [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr WindowFromPoint(POINT point); [DllImport("user32.dll", SetLastError = true)] private static extern IntPtr GetAncestor(IntPtr hWnd, uint gaFlags); const uint GA_PARENT = 1; const uint GA_ROOT = 2; const uint GA_ROOTOWNER = 3; // そのウィンドウハンドルをもつウィンドウは存在するか? 存在するなら0以外の値を返す [DllImport("user32.dll", CharSet = CharSet.Auto)] static extern int IsWindow(IntPtr hWnd); // 半透明にしたウィンドウハンドルのリスト List<IntPtr> Handles = new List<IntPtr>(); // Targetラベルがクリックされたらマウスキャプチャ private void label1_MouseDown(object sender, MouseEventArgs e) { label1.Capture = true; } // マウスが離されたらマウスポインタがあるウィンドウのハンドルを取得し、 // ウィンドウを半透明にする private void label1_MouseUp(object sender, MouseEventArgs e) { POINT point = new POINT(); point.x = Control.MousePosition.X; point.y = Control.MousePosition.Y; IntPtr handle = WindowFromPoint(point); IntPtr rootHandle = GetAncestor(handle, GA_ROOT); // ドロップ先が自分自身のときはなにもしない if(rootHandle == this.Handle) return; // ウィンドウを半透明にしたらリストに保存 if(SetOpacity(rootHandle, (byte)numericUpDown1.Value)) { Handles.Add(rootHandle); Handles = Handles.Distinct().ToList(); // 重複は取り除く } } // [元に戻す]が選択されたら半透明の状態からもとに戻す private void buttonReset_Click(object sender, EventArgs e) { ResetAll(); } // アプリケーションが終了するときも半透明にしたウィンドウをもとの状態に戻す protected override void OnClosing(CancelEventArgs e) { ResetAll(); base.OnClosing(e); } void ResetAll() { foreach(IntPtr handle in Handles) { // ウィンドウが存在することが確認できたらもとに戻す if(IsWindow(handle) != 0) SetOpacity(handle, 255); } Handles.Clear(); } } |