首先是多屏,我的需求是只显示在第二块屏幕上,而且第一块屏幕上的操作不能影响到第二块屏幕.
如果连了另一块屏幕,在打开exe的时候的配置框可以选择显示在哪块屏幕上
如果选择了第二块,不删除Data文件夹,回到Unity取消勾选Display Resolution Diag,下次打开直接跳到第二快屏幕上.
二 解决第二块屏幕的后台
但是如果仅仅这样,会遇到一个不大大小的问题-在主屏幕点击一下,第二块屏幕的显示就跑到后台去了.
我是想让第二块屏幕,不受第一块屏幕的影响而跑到后台.
经过尝试,
如果勾选就可以了.
三.获取当前窗口句柄
当前窗口就是它的进程,之前一直搜索窗口的办法,没有啥好办法
然后用了进程解决了.
参照:http://www.jb51.net/article/36226.htm
代码:
public class User32API { private static Hashtable processWnd = null; public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam); static User32API() { if (processWnd == null) { processWnd = new Hashtable(); } } [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)] public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam); [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)] public static extern IntPtr GetParent(IntPtr hWnd); [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId); [DllImport("user32.dll", EntryPoint = "IsWindow")] public static extern bool IsWindow(IntPtr hWnd); [DllImport("kernel32.dll", EntryPoint = "SetLastError")] public static extern void SetLastError(uint dwErrCode); public static IntPtr GetCurrentWindowHandle() { IntPtr ptrWnd = IntPtr.Zero; uint uiPid = (uint)Process.GetCurrentProcess().Id; // 当前进程 ID object objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄 { return ptrWnd; } else { ptrWnd = IntPtr.Zero; } } bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid); // 枚举窗口返回 false 并且没有错误号时表明获取成功 if (!bResult && Marshal.GetLastWin32Error() == 0) { objWnd = processWnd[uiPid]; if (objWnd != null) { ptrWnd = (IntPtr)objWnd; } } return ptrWnd; } private static bool EnumWindowsProc(IntPtr hwnd, uint lParam) { uint uiPid = 0; if (GetParent(hwnd) == IntPtr.Zero) { GetWindowThreadProcessId(hwnd, ref uiPid); if (uiPid == lParam) // 找到进程对应的主窗口句柄 { processWnd[uiPid] = hwnd; // 把句柄缓存起来 SetLastError(0); // 设置无错误 return false; // 返回 false 以终止枚举窗口 } } return true; } }四.最大化和最小化
[DllImport("user32.dll")] public static extern bool ShowWindow(System.IntPtr hwnd, int nCmdShow); public void SetWindowMin() { ShowWindow(User32API.GetCurrentWindowHandle(), 2);//最小化 } public void SetWindowMax() { ShowWindow(User32API.GetCurrentWindowHandle(), 3);//最小化 }五.定义接口
本地Unity程序作为服务端(C#做服务端比较扯淡)
private Socket m_server; void Start () { IPAddress local = IPAddress.Parse("127.0.0.1"); IPEndPoint iep=new IPEndPoint(local,5099); m_server=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); m_server.Bind(iep); m_server.Listen(5); Thread ServerThread=new Thread(ServerAccept); ServerThread.Start(); } void Update () { } private void ServerAccept() { while (true) { Debug.Log("开始接收客户端信息"); // 得到包含客户端信息的套接字 Socket client = m_server.Accept(); Debug.Log("接收到客户端"); //创建消息服务线程对象 ServerThread newclient = new ServerThread(client); //把ClientThread 类的ClientService方法委托给线程 Thread newthread = new Thread(newclient.ClientService); // 启动消息服务线程 newthread.Start(20);//接收的长度大小 } } public void OnApplicationQuit() { Debug.Log("exit"); m_server.Close(); } using System.Collections; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using UnityEngine; public class ServerThread { private Socket m_client; public ServerThread(Socket client) { this.m_client = client; } public void ClientService(object param) { int fixedsize = (int)param; string data = null; byte[] bytes = null; Debug.Log("新客户连接建立:" + ((IPEndPoint)m_client.RemoteEndPoint).Address); while ((bytes = ReceiveMessage(m_client, fixedsize)).Length != 0) { data = System.Text.Encoding.ASCII.GetString(bytes, 0, fixedsize); Debug.Log("收到的数据:" + data); // 处理客户端发来的消息,这里是转化为大写字母 data=data.Trim( '\0'); ExecuteOrder(data); } //关闭套接字 m_client.Close(); Debug.Log("客户关闭连接:" + ((IPEndPoint)m_client.RemoteEndPoint).Address); } byte[] ReceiveMessage(Socket s, int size) { size = 20; int offset = 0; int recv; int dataleft = size; byte[] msg = new byte[size]; while (dataleft > 0) { recv = s.Receive(msg, offset, dataleft, 0); if (recv == 0) { break; } offset += recv; dataleft -= recv; } return msg; } public void ExecuteOrder(string order) { //Debug.Log(sb.ToString().Length); switch (order) { case "start": Debug.Log("进入start case"); Loom.QueueOnMainThread( () => { CharacterManager.Instance.GetComponent<CharacterManager>().isSpeaking = true; }); break; case "stop": Loom.QueueOnMainThread( () => { CharacterManager.Instance.GetComponent<CharacterManager>().isSpeaking = false; }); Debug.Log("stop case"); break; case "max": Loom.QueueOnMainThread( () => { DisplayScript.Instance.SetWindowMax(); }); break; case "min": Loom.QueueOnMainThread( () => { DisplayScript.Instance.SetWindowMin(); }); break; } } }注意: data=data.Trim( '\0');
因为byte中的0转换为char是 '\0',而不是' ',' '的ascii码是32.
