话不多说,先上代码
(有一部分是网上捞下来的,鉴于网上代码有很多bug,例如 启动时其他窗口的线程置前会导致原生窗口最大化最小化隐藏失败,app中任何地方都需要移动窗口等,项目中都解决了,把代码分享给大家~ 这就是话不多说!)
public class CZWnd : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler
{
public Rect screenPosition;
[DllImport("user32.dll")]
static extern IntPtr SetWindowLong(IntPtr hwnd, int _nIndex, int dwNewLong);
[DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool ReleaseCapture();
[DllImport("user32.dll")]
public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string className, string windowName);
//[DllImport("user32.dll")]
//private static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32")]
public static extern int GetSystemMetrics(int nIndex); //通过设置不同的标识符就可以获取系统分辨率、窗体显示区域的宽度和高度、滚动
const int SM_CXSCREEN = 0x00000000;
const int SM_CYSCREEN = 0x00000001;
const uint SWP_SHOWWINDOW = 0x0040;
const int GWL_STYLE = -16;
const int WS_BORDER = 1;
const int WS_POPUP = 0x800000;
const int SW_SHOWMINIMIZED = 2; //{最小化, 激活}
const int SW_SHOWMAXIMIZED = 3; //{最大化, 激活}
public void btn_onclick()
{ //最小化
ShowWindow(GetForegroundWindow(), SW_SHOWMINIMIZED);
}
public void btn_onclickxx()
{ //最大化
ShowWindow(GetForegroundWindow(), SW_SHOWMAXIMIZED);
}
IntPtr Handle;
float xx;
bool bx;
void Awake()
{
Screen.fullScreen = false;
}
void Start()
{
bx = false;
xx = 0f;
#if UNITY_STANDALONE_WIN
screenPosition = new Rect(((int)GetSystemMetrics(SM_CXSCREEN) - Screen.width) / 2, ((int)GetSystemMetrics(SM_CYSCREEN) - Screen.height) / 2, 800, 600);
//获取当前应用的句柄
IntPtr intPtr = FindWindow(null, Application.productName);
Handle = intPtr; //Handle = GetForegroundWindow();
SetWindowLong(Handle, GWL_STYLE, WS_POPUP);//将网上的WS_BORDER替换成WS_POPUP
SetWindowPos(Handle, 0, (int)screenPosition.x, (int)screenPosition.y, 800, 600, SWP_SHOWWINDOW);
bool result = SetWindowPos(Handle, 0, (int)screenPosition.x, (int)screenPosition.y, 800, 600, SWP_SHOWWINDOW);//exe居中显示;
#endif
}
void Update()
{
#if UNITY_STANDALONE_WIN
if (Input.GetMouseButtonDown(0) && canMove && inMove)
{
xx = 0f;
bx = true;
}
if (bx && xx >= 0.02f)
{ //这样做为了区分界面上面其它需要滑动的操作
ReleaseCapture();
SendMessage(Handle, 0xA1, 0x02, 0);
SendMessage(Handle, 0x0202, 0, 0);
}
if (bx)
xx += Time.deltaTime;
if (Input.GetMouseButtonUp(0))
{
xx = 0f;
bx = false;
}
#endif
}
bool canMove;
bool inMove;
public void OnPointerUp(PointerEventData eventData)
{
inMove = false;
canMove = false;
Debug.Log("inMove" + inMove + " --- " + "canMove" + canMove);
}
public void OnPointerDown(PointerEventData eventData)
{
canMove = true;
Debug.Log("canMove" + canMove);
public void OnDrag(PointerEventData eventData)
{
//inMove = true;
}
public void OnPointerEnter(PointerEventData eventData)
{
inMove = true;
}
public void OnPointerExit(PointerEventData eventData)
{
inMove = false;
}
}
上面代码脚本放入可以拖动的UI中即可实现的拖动
但是还有一个问题就是当等待exe运行时,如果手闲不住的小伙伴会点开其他的窗口, 由于我们使用的window原生的API关闭的原生的窗口栏,它是优先前置的窗口隐藏的,会导致我们的exe窗口隐藏失败,但是我们手贱点开的另一个窗口会窗口栏隐藏,异常的尴尬(笑哭),所以我们要在Awake()中将窗口前置并且给他最高线程权限,这样就可以避免这个bug了,用到的API为SetForegroundWindow(),IsIconic(),具体方法看这锅 - Unity防止同一个exe多次启动
没办法 就是这么懒 自己去改吧 哇哈哈哈哈哈 (逃