比较适合的内容:
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFile
{
public int structSize = 0;
public IntPtr dlgOwner = IntPtr.Zero;
public IntPtr instance = IntPtr.Zero;
public string filter = null;
public string customFilter = null;
public int maxCustFilter = 0;
public int filterIndex = 0;
public string file = null;
public int maxFile = 0;
public string fileTitle = null;
public int maxFileTitle = 0;
public string initialDir = null;
public string title = null;
public int flags = 0;
public short fileOffset = 0;
public short fileExtension = 0;
public string defExt = null;
public IntPtr custData = IntPtr.Zero;
public IntPtr hook = IntPtr.Zero;
public string templateName = null;
public IntPtr reservedPtr = IntPtr.Zero;
public int reservedInt = 0;
public int flagsEx = 0;
}
public class WindowDll
{
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetOpenFileName([In, Out] OpenFile of);
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetSaveFileName([In, Out] OpenFile ofn);
/// <summary>
/// 用于获取当前Player窗口指针。
/// </summary>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
/// <summary>
/// 打开文件
/// </summary>
/// <param name="filter">过滤器</param>
/// <param name="m_defaultPath">默认打开的路径</param>
/// <returns></returns>
public static string OpenFile(string filter, string m_defaultPath)
{
OpenFile of = new OpenFile();
of.structSize = Marshal.SizeOf(of);
of.filter = filter;
of.file = new string(new char[256]);
of.maxFile = of.file.Length;
of.fileTitle = new string(new char[64]);
of.maxFileTitle = of.fileTitle.Length;
of.dlgOwner = GetForegroundWindow();
string defaultPath = m_defaultPath;
defaultPath = defaultPath.Replace('/', '\\');
of.initialDir = defaultPath;
of.title = "小宝贝儿,Word很大你忍一下";
of.defExt = "DOCX";
of.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
if (WindowDll.GetOpenFileName(of))
{
Debug.Log("Selected file with full path: {0}" + of.file);
return of.file;
}
return string.Empty;
}
}
其中需要注意的有一个地方就是,当对话框打开之后,鼠标点击其他位置,对话框会聚焦失败,在Unity里面会导致Unity崩溃,发布出来之后主线程卡死,不切回对话框的话,会无法往下走。
解决方案:
(1)、把对话框一直放在最前方,也就是上面的贴的代码
(2)、使用GetActiveWindow() ,也会解决这个问题
两个方案也是有区别的,查了一下资料 (21条消息) GetActiveWindow与GetForegroundWindow两者有何区别?_彷徨而立的博客-CSDN博客_getforegroundwindow
大概意思就是GetForegroundWindow是系统级别的最前方,而GetActiveWindow是你当前线程级别的最前方。
测试一下两者的区别:
GetForegroundWindow:
登录QQ的情况下,因为QQ是保持在系统最前方的,用GetForegroundWindow获取最前方的窗口的时候,拿到的还是对话框窗口,只是当打开Console界面的时候,点击Console界面会导致该界面保持在最前方,然后Unity的代码产生编译,导致Unity出现BUG
Reload Assembly called from managed code directly. This will cause a crash. You should never refresh assets in synchronous mode or enter playmode synchronously from script code.
GetActiveWindow:
与GetForegroundWindow一样的问题
发布没有测试,如果有发布测试之后有不同反应的,可以评论留言