mirror of
https://github.com/maxartz15/TextureCombiner.git
synced 2024-11-09 23:22:55 +01:00
1165a4e4a8
P4 -> GitHub sync.
495 lines
16 KiB
C#
495 lines
16 KiB
C#
/* * * * *
|
|
* This is a collection of Win API helpers. Mainly dealing with window message hooks
|
|
* and file drag&drop support for Windows standalone Unity applications.
|
|
*
|
|
* 2019.11.28 - Changed the "UnityDragAndDropHook" class to a static class. This
|
|
* has been done for IL2CPP support. IL2CPP can not marshall instance method
|
|
* callbacks passed to native code. So the callbacks must be static methods.
|
|
* Therefore all fields involved also need to be static.
|
|
*
|
|
* The MIT License (MIT)
|
|
*
|
|
* Copyright (c) 2018 Markus Göbel (Bunny83)
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* * * * */
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace B83.Win32
|
|
{
|
|
public enum HookType : int
|
|
{
|
|
WH_JOURNALRECORD = 0,
|
|
WH_JOURNALPLAYBACK = 1,
|
|
WH_KEYBOARD = 2,
|
|
WH_GETMESSAGE = 3,
|
|
WH_CALLWNDPROC = 4,
|
|
WH_CBT = 5,
|
|
WH_SYSMSGFILTER = 6,
|
|
WH_MOUSE = 7,
|
|
WH_HARDWARE = 8,
|
|
WH_DEBUG = 9,
|
|
WH_SHELL = 10,
|
|
WH_FOREGROUNDIDLE = 11,
|
|
WH_CALLWNDPROCRET = 12,
|
|
WH_KEYBOARD_LL = 13,
|
|
WH_MOUSE_LL = 14
|
|
}
|
|
|
|
// windows messages
|
|
public enum WM : uint
|
|
{
|
|
NULL = 0x0000,
|
|
CREATE = 0x0001,
|
|
DESTROY = 0x0002,
|
|
MOVE = 0x0003,
|
|
SIZE = 0x0005,
|
|
ACTIVATE = 0x0006,
|
|
SETFOCUS = 0x0007,
|
|
KILLFOCUS = 0x0008,
|
|
ENABLE = 0x000A,
|
|
SETREDRAW = 0x000B,
|
|
SETTEXT = 0x000C,
|
|
GETTEXT = 0x000D,
|
|
GETTEXTLENGTH = 0x000E,
|
|
PAINT = 0x000F,
|
|
CLOSE = 0x0010,
|
|
QUERYENDSESSION = 0x0011,
|
|
QUERYOPEN = 0x0013,
|
|
ENDSESSION = 0x0016,
|
|
QUIT = 0x0012,
|
|
ERASEBKGND = 0x0014,
|
|
SYSCOLORCHANGE = 0x0015,
|
|
SHOWWINDOW = 0x0018,
|
|
WININICHANGE = 0x001A,
|
|
SETTINGCHANGE = WININICHANGE,
|
|
DEVMODECHANGE = 0x001B,
|
|
ACTIVATEAPP = 0x001C,
|
|
FONTCHANGE = 0x001D,
|
|
TIMECHANGE = 0x001E,
|
|
CANCELMODE = 0x001F,
|
|
SETCURSOR = 0x0020,
|
|
MOUSEACTIVATE = 0x0021,
|
|
CHILDACTIVATE = 0x0022,
|
|
QUEUESYNC = 0x0023,
|
|
GETMINMAXINFO = 0x0024,
|
|
PAINTICON = 0x0026,
|
|
ICONERASEBKGND = 0x0027,
|
|
NEXTDLGCTL = 0x0028,
|
|
SPOOLERSTATUS = 0x002A,
|
|
DRAWITEM = 0x002B,
|
|
MEASUREITEM = 0x002C,
|
|
DELETEITEM = 0x002D,
|
|
VKEYTOITEM = 0x002E,
|
|
CHARTOITEM = 0x002F,
|
|
SETFONT = 0x0030,
|
|
GETFONT = 0x0031,
|
|
SETHOTKEY = 0x0032,
|
|
GETHOTKEY = 0x0033,
|
|
QUERYDRAGICON = 0x0037,
|
|
COMPAREITEM = 0x0039,
|
|
GETOBJECT = 0x003D,
|
|
COMPACTING = 0x0041,
|
|
[Obsolete]
|
|
COMMNOTIFY = 0x0044,
|
|
WINDOWPOSCHANGING = 0x0046,
|
|
WINDOWPOSCHANGED = 0x0047,
|
|
[Obsolete]
|
|
POWER = 0x0048,
|
|
COPYDATA = 0x004A,
|
|
CANCELJOURNAL = 0x004B,
|
|
NOTIFY = 0x004E,
|
|
INPUTLANGCHANGEREQUEST = 0x0050,
|
|
INPUTLANGCHANGE = 0x0051,
|
|
TCARD = 0x0052,
|
|
HELP = 0x0053,
|
|
USERCHANGED = 0x0054,
|
|
NOTIFYFORMAT = 0x0055,
|
|
CONTEXTMENU = 0x007B,
|
|
STYLECHANGING = 0x007C,
|
|
STYLECHANGED = 0x007D,
|
|
DISPLAYCHANGE = 0x007E,
|
|
GETICON = 0x007F,
|
|
SETICON = 0x0080,
|
|
NCCREATE = 0x0081,
|
|
NCDESTROY = 0x0082,
|
|
NCCALCSIZE = 0x0083,
|
|
NCHITTEST = 0x0084,
|
|
NCPAINT = 0x0085,
|
|
NCACTIVATE = 0x0086,
|
|
GETDLGCODE = 0x0087,
|
|
SYNCPAINT = 0x0088,
|
|
NCMOUSEMOVE = 0x00A0,
|
|
NCLBUTTONDOWN = 0x00A1,
|
|
NCLBUTTONUP = 0x00A2,
|
|
NCLBUTTONDBLCLK = 0x00A3,
|
|
NCRBUTTONDOWN = 0x00A4,
|
|
NCRBUTTONUP = 0x00A5,
|
|
NCRBUTTONDBLCLK = 0x00A6,
|
|
NCMBUTTONDOWN = 0x00A7,
|
|
NCMBUTTONUP = 0x00A8,
|
|
NCMBUTTONDBLCLK = 0x00A9,
|
|
NCXBUTTONDOWN = 0x00AB,
|
|
NCXBUTTONUP = 0x00AC,
|
|
NCXBUTTONDBLCLK = 0x00AD,
|
|
INPUT_DEVICE_CHANGE = 0x00FE,
|
|
INPUT = 0x00FF,
|
|
KEYFIRST = 0x0100,
|
|
KEYDOWN = 0x0100,
|
|
KEYUP = 0x0101,
|
|
CHAR = 0x0102,
|
|
DEADCHAR = 0x0103,
|
|
SYSKEYDOWN = 0x0104,
|
|
SYSKEYUP = 0x0105,
|
|
SYSCHAR = 0x0106,
|
|
SYSDEADCHAR = 0x0107,
|
|
UNICHAR = 0x0109,
|
|
KEYLAST = 0x0108,
|
|
IME_STARTCOMPOSITION = 0x010D,
|
|
IME_ENDCOMPOSITION = 0x010E,
|
|
IME_COMPOSITION = 0x010F,
|
|
IME_KEYLAST = 0x010F,
|
|
INITDIALOG = 0x0110,
|
|
COMMAND = 0x0111,
|
|
SYSCOMMAND = 0x0112,
|
|
TIMER = 0x0113,
|
|
HSCROLL = 0x0114,
|
|
VSCROLL = 0x0115,
|
|
INITMENU = 0x0116,
|
|
INITMENUPOPUP = 0x0117,
|
|
MENUSELECT = 0x011F,
|
|
MENUCHAR = 0x0120,
|
|
ENTERIDLE = 0x0121,
|
|
MENURBUTTONUP = 0x0122,
|
|
MENUDRAG = 0x0123,
|
|
MENUGETOBJECT = 0x0124,
|
|
UNINITMENUPOPUP = 0x0125,
|
|
MENUCOMMAND = 0x0126,
|
|
CHANGEUISTATE = 0x0127,
|
|
UPDATEUISTATE = 0x0128,
|
|
QUERYUISTATE = 0x0129,
|
|
CTLCOLORMSGBOX = 0x0132,
|
|
CTLCOLOREDIT = 0x0133,
|
|
CTLCOLORLISTBOX = 0x0134,
|
|
CTLCOLORBTN = 0x0135,
|
|
CTLCOLORDLG = 0x0136,
|
|
CTLCOLORSCROLLBAR = 0x0137,
|
|
CTLCOLORSTATIC = 0x0138,
|
|
MOUSEFIRST = 0x0200,
|
|
MOUSEMOVE = 0x0200,
|
|
LBUTTONDOWN = 0x0201,
|
|
LBUTTONUP = 0x0202,
|
|
LBUTTONDBLCLK = 0x0203,
|
|
RBUTTONDOWN = 0x0204,
|
|
RBUTTONUP = 0x0205,
|
|
RBUTTONDBLCLK = 0x0206,
|
|
MBUTTONDOWN = 0x0207,
|
|
MBUTTONUP = 0x0208,
|
|
MBUTTONDBLCLK = 0x0209,
|
|
MOUSEWHEEL = 0x020A,
|
|
XBUTTONDOWN = 0x020B,
|
|
XBUTTONUP = 0x020C,
|
|
XBUTTONDBLCLK = 0x020D,
|
|
MOUSEHWHEEL = 0x020E,
|
|
MOUSELAST = 0x020E,
|
|
PARENTNOTIFY = 0x0210,
|
|
ENTERMENULOOP = 0x0211,
|
|
EXITMENULOOP = 0x0212,
|
|
NEXTMENU = 0x0213,
|
|
SIZING = 0x0214,
|
|
CAPTURECHANGED = 0x0215,
|
|
MOVING = 0x0216,
|
|
POWERBROADCAST = 0x0218,
|
|
DEVICECHANGE = 0x0219,
|
|
MDICREATE = 0x0220,
|
|
MDIDESTROY = 0x0221,
|
|
MDIACTIVATE = 0x0222,
|
|
MDIRESTORE = 0x0223,
|
|
MDINEXT = 0x0224,
|
|
MDIMAXIMIZE = 0x0225,
|
|
MDITILE = 0x0226,
|
|
MDICASCADE = 0x0227,
|
|
MDIICONARRANGE = 0x0228,
|
|
MDIGETACTIVE = 0x0229,
|
|
MDISETMENU = 0x0230,
|
|
ENTERSIZEMOVE = 0x0231,
|
|
EXITSIZEMOVE = 0x0232,
|
|
DROPFILES = 0x0233,
|
|
MDIREFRESHMENU = 0x0234,
|
|
IME_SETCONTEXT = 0x0281,
|
|
IME_NOTIFY = 0x0282,
|
|
IME_CONTROL = 0x0283,
|
|
IME_COMPOSITIONFULL = 0x0284,
|
|
IME_SELECT = 0x0285,
|
|
IME_CHAR = 0x0286,
|
|
IME_REQUEST = 0x0288,
|
|
IME_KEYDOWN = 0x0290,
|
|
IME_KEYUP = 0x0291,
|
|
MOUSEHOVER = 0x02A1,
|
|
MOUSELEAVE = 0x02A3,
|
|
NCMOUSEHOVER = 0x02A0,
|
|
NCMOUSELEAVE = 0x02A2,
|
|
WTSSESSION_CHANGE = 0x02B1,
|
|
TABLET_FIRST = 0x02c0,
|
|
TABLET_LAST = 0x02df,
|
|
CUT = 0x0300,
|
|
COPY = 0x0301,
|
|
PASTE = 0x0302,
|
|
CLEAR = 0x0303,
|
|
UNDO = 0x0304,
|
|
RENDERFORMAT = 0x0305,
|
|
RENDERALLFORMATS = 0x0306,
|
|
DESTROYCLIPBOARD = 0x0307,
|
|
DRAWCLIPBOARD = 0x0308,
|
|
PAINTCLIPBOARD = 0x0309,
|
|
VSCROLLCLIPBOARD = 0x030A,
|
|
SIZECLIPBOARD = 0x030B,
|
|
ASKCBFORMATNAME = 0x030C,
|
|
CHANGECBCHAIN = 0x030D,
|
|
HSCROLLCLIPBOARD = 0x030E,
|
|
QUERYNEWPALETTE = 0x030F,
|
|
PALETTEISCHANGING = 0x0310,
|
|
PALETTECHANGED = 0x0311,
|
|
HOTKEY = 0x0312,
|
|
PRINT = 0x0317,
|
|
PRINTCLIENT = 0x0318,
|
|
APPCOMMAND = 0x0319,
|
|
THEMECHANGED = 0x031A,
|
|
CLIPBOARDUPDATE = 0x031D,
|
|
DWMCOMPOSITIONCHANGED = 0x031E,
|
|
DWMNCRENDERINGCHANGED = 0x031F,
|
|
DWMCOLORIZATIONCOLORCHANGED = 0x0320,
|
|
DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
|
|
GETTITLEBARINFOEX = 0x033F,
|
|
HANDHELDFIRST = 0x0358,
|
|
HANDHELDLAST = 0x035F,
|
|
AFXFIRST = 0x0360,
|
|
AFXLAST = 0x037F,
|
|
PENWINFIRST = 0x0380,
|
|
PENWINLAST = 0x038F,
|
|
APP = 0x8000,
|
|
USER = 0x0400,
|
|
CPL_LAUNCH = USER + 0x1000,
|
|
CPL_LAUNCHED = USER + 0x1001,
|
|
SYSTIMER = 0x118,
|
|
}
|
|
|
|
// WH_CALLWNDPROC
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CWPSTRUCT
|
|
{
|
|
public IntPtr lParam;
|
|
public IntPtr wParam;
|
|
public WM message;
|
|
public IntPtr hwnd;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct POINT
|
|
{
|
|
public int x, y;
|
|
public POINT(int aX, int aY)
|
|
{
|
|
x = aX;
|
|
y = aY;
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return "(" + x + ", " + y + ")";
|
|
}
|
|
}
|
|
|
|
//WH_GETMESSAGE
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct MSG
|
|
{
|
|
public IntPtr hwnd;
|
|
public WM message;
|
|
public IntPtr wParam;
|
|
public IntPtr lParam;
|
|
public ushort time;
|
|
public POINT pt;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT
|
|
{
|
|
public int Left, Top, Right, Bottom;
|
|
|
|
public RECT(int left, int top, int right, int bottom)
|
|
{
|
|
Left = left;
|
|
Top = top;
|
|
Right = right;
|
|
Bottom = bottom;
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return "(" + Left + ", " + Top + ", " + Right + ", " + Bottom + ")";
|
|
}
|
|
}
|
|
|
|
public delegate IntPtr HookProc(int code, IntPtr wParam, ref MSG lParam);
|
|
public delegate bool EnumThreadDelegate(IntPtr Hwnd, IntPtr lParam);
|
|
|
|
#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
|
|
|
public static class Window
|
|
{
|
|
[DllImport("user32.dll")]
|
|
public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool IsWindowVisible(IntPtr hWnd);
|
|
|
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount);
|
|
public static string GetClassName(IntPtr hWnd)
|
|
{
|
|
var sb = new System.Text.StringBuilder(256);
|
|
int count = GetClassName(hWnd, sb, 256);
|
|
return sb.ToString(0, count);
|
|
}
|
|
|
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
static extern int GetWindowTextLength(IntPtr hWnd);
|
|
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
|
|
public static string GetWindowText(IntPtr hWnd)
|
|
{
|
|
int length = GetWindowTextLength(hWnd) + 2;
|
|
var sb = new System.Text.StringBuilder(length);
|
|
int count = GetWindowText(hWnd, sb, length);
|
|
return sb.ToString(0, count);
|
|
}
|
|
}
|
|
|
|
public static class WinAPI
|
|
{
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
|
[DllImport("kernel32.dll")]
|
|
public static extern uint GetCurrentThreadId();
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc lpfn, IntPtr hMod, uint dwThreadId);
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
|
|
[DllImport("user32.dll")]
|
|
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, ref MSG lParam);
|
|
|
|
[DllImport("shell32.dll")]
|
|
public static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);
|
|
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
|
|
public static extern uint DragQueryFile(IntPtr hDrop, uint iFile, System.Text.StringBuilder lpszFile, uint cch);
|
|
[DllImport("shell32.dll")]
|
|
public static extern void DragFinish(IntPtr hDrop);
|
|
|
|
[DllImport("shell32.dll")]
|
|
public static extern void DragQueryPoint(IntPtr hDrop, out POINT pos);
|
|
}
|
|
#endif
|
|
|
|
|
|
public static class UnityDragAndDropHook
|
|
{
|
|
public delegate void DroppedFilesEvent(List<string> aPathNames, POINT aDropPoint);
|
|
#pragma warning disable CS0067
|
|
public static event DroppedFilesEvent OnDroppedFiles;
|
|
#pragma warning restore CS0067
|
|
|
|
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN
|
|
|
|
private static uint threadId;
|
|
private static IntPtr mainWindow = IntPtr.Zero;
|
|
private static IntPtr m_Hook;
|
|
private static string m_ClassName = "UnityWndClass";
|
|
|
|
// attribute required for IL2CPP, also has to be a static method
|
|
[AOT.MonoPInvokeCallback(typeof(EnumThreadDelegate))]
|
|
private static bool EnumCallback(IntPtr W, IntPtr _)
|
|
{
|
|
if (Window.IsWindowVisible(W) && (mainWindow == IntPtr.Zero || (m_ClassName != null && Window.GetClassName(W) == m_ClassName)))
|
|
{
|
|
mainWindow = W;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static void InstallHook()
|
|
{
|
|
threadId = WinAPI.GetCurrentThreadId();
|
|
if (threadId > 0)
|
|
Window.EnumThreadWindows(threadId, EnumCallback, IntPtr.Zero);
|
|
|
|
var hModule = WinAPI.GetModuleHandle(null);
|
|
m_Hook = WinAPI.SetWindowsHookEx(HookType.WH_GETMESSAGE, Callback, hModule, threadId);
|
|
// Allow dragging of files onto the main window. generates the WM_DROPFILES message
|
|
WinAPI.DragAcceptFiles(mainWindow, true);
|
|
}
|
|
public static void UninstallHook()
|
|
{
|
|
WinAPI.UnhookWindowsHookEx(m_Hook);
|
|
WinAPI.DragAcceptFiles(mainWindow, false);
|
|
m_Hook = IntPtr.Zero;
|
|
}
|
|
|
|
// attribute required for IL2CPP, also has to be a static method
|
|
[AOT.MonoPInvokeCallback(typeof(HookProc))]
|
|
private static IntPtr Callback(int code, IntPtr wParam, ref MSG lParam)
|
|
{
|
|
if (code == 0 && lParam.message == WM.DROPFILES)
|
|
{
|
|
POINT pos;
|
|
WinAPI.DragQueryPoint(lParam.wParam, out pos);
|
|
|
|
// 0xFFFFFFFF as index makes the method return the number of files
|
|
uint n = WinAPI.DragQueryFile(lParam.wParam, 0xFFFFFFFF, null, 0);
|
|
var sb = new System.Text.StringBuilder(1024);
|
|
|
|
List<string> result = new List<string>();
|
|
for (uint i = 0; i < n; i++)
|
|
{
|
|
int len = (int)WinAPI.DragQueryFile(lParam.wParam, i, sb, 1024);
|
|
result.Add(sb.ToString(0, len));
|
|
sb.Length = 0;
|
|
}
|
|
WinAPI.DragFinish(lParam.wParam);
|
|
if (OnDroppedFiles != null)
|
|
OnDroppedFiles(result, pos);
|
|
}
|
|
return WinAPI.CallNextHookEx(m_Hook, code, wParam, ref lParam);
|
|
}
|
|
#else
|
|
public static void InstallHook()
|
|
{
|
|
}
|
|
public static void UninstallHook()
|
|
{
|
|
}
|
|
#endif
|
|
}
|
|
}
|