Skip to content

Instantly share code, notes, and snippets.

@Forenard
Created August 4, 2022 18:42
Show Gist options
  • Save Forenard/39089e0efafeb10944bd91b92c32683a to your computer and use it in GitHub Desktop.
Save Forenard/39089e0efafeb10944bd91b92c32683a to your computer and use it in GitHub Desktop.
For Unity exe builds, make the specified background color transparent and display everything else on top.
/// こちらはオリジナルのソースコード
/// https://gist.github.com/wakagomo/fe74ec4a7b74f2e3299a7f2ecc359722
/// に追記したものです。
///
/// オリジナルとの違い:
/// - 0x00FF00が透過する
/// - 透過していない部分は常に最上面に表示されるが、透過した部分はそのままクリックできる
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace WindowsAPI
{
/// <summary>
/// Make the window transparent.
/// </summary>
public class TransparentWindow : MonoBehaviour
{
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
#region WINDOWS API
/// <summary>
/// Returned by the GetThemeMargins function to define the margins of windows that have visual styles applied.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/desktop/api/uxtheme/ns-uxtheme-_margins
private struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
/// <summary>
/// Retrieves the window handle to the active window attached to the calling thread's message queue.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getactivewindow
[DllImport("User32.dll")]
private static extern IntPtr GetActiveWindow();
/// <summary>
/// Changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowlonga
[DllImport("User32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
/// <summary>
/// Changes the size, position, and Z order of a child, pop-up, or top-level window. These windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setwindowpos
[DllImport("User32.dll")]
private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
/// <summary>
/// Extends the window frame into the client area.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/desktop/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea
[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
/// <summary>
/// Sets the opacity and transparency color key of a layered window.
/// </summary>
/// https://docs.microsoft.com/ja-JP/windows/win32/api/winuser/nf-winuser-setlayeredwindowattributes
[DllImport("User32.dll")]
private static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey,byte bAlpha, uint dwNewLong);
/// <summary>
/// Brings the thread that created the specified window into the foreground and activates the window.
/// Keyboard input is directed to the window, and various visual cues are changed for the user.
/// The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.
/// </summary>
/// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
#endregion
private void Awake()
{
IntPtr windowHandle = GetActiveWindow();
{ // SetWindowLong
const int GWL_STYLE = -16;
const int GWL_EXSTYLE = -20;
const uint WS_POPUP = 0x80000000;
const uint WS_EX_LAYERD = 0x080000;
const uint WS_EX_TRANSPARENT = 0x00000020;
SetWindowLong(windowHandle, GWL_STYLE, WS_POPUP);
SetWindowLong(windowHandle, GWL_EXSTYLE, WS_EX_LAYERD);
}
{ // SetWindowPos
IntPtr HWND_TOPMOST = new IntPtr(-1);
const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOMOVE = 0x0002;
const uint SWP_NOACTIVE = 0x0010;
const uint SWP_SHOWWINDOW = 0x0040;
SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
}
{ // DwmExtendFrameIntoClientArea
MARGINS margins = new MARGINS()
{
cxLeftWidth = -1
};
DwmExtendFrameIntoClientArea(windowHandle, ref margins);
}
{ // SetLayeredWindowAttributes
const uint COLOR_KEY = 0x0000FF00; // Green
const byte B_ALPHA_0 = 0x00;
const byte B_ALPHA_255 = 0xFF;
// bAlpha を使用して、レイヤードウィンドウの不透明度を決定します
const uint LWA_ALPHA = 0x2;
// 透明度の色として crKey を使用します。
const uint LWA_COLORKEY = 0x1;
SetLayeredWindowAttributes(windowHandle, COLOR_KEY, B_ALPHA_255, LWA_COLORKEY);
}
{ // SetForegroundWindow
SetForegroundWindow(windowHandle);
}
}
#endif // !UNITY_EDITOR && UNITY_STANDALONE_WIN
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment