Unity调用操作系统的dialog
发表于2018-08-14
有个需求,就是在扩展编辑器功能时,有一些配置文件需要读取,现在希望能选取这个东西,而不是每次手填地址。
找了半天unity提供的组件,发现没有提供这个功能呀,这可怎么办?
突然想到unity用的是c#呀,那能不能直接使用c#的系统弹窗,想到就查,结果竟然还真的可以,下面我们来看看要怎么搞。下面就来看看调用操作系统的dialog的方法。
参考:https://www.jianshu.com/p/e3ef2f45bda0
代码如下:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class OpenFileName { 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; }
/// <summary> /// 从dll加载对话框 /// </summary> public class DllLoadDialog { [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetOpenFileName([In, Out] OpenFileName ofn); [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool GetSaveFileName([In, Out] OpenFileName ofn); [DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern IntPtr SHBrowseForFolder([In, Out] OpenFileDir ofn); [DllImport("shell32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)] public static extern bool SHGetPathFromIDList([In] IntPtr pidl, [In, Out] char[] fileName); }
public class OpenDialog { /// <summary> /// 打开文件对话框 /// </summary> /// <returns></returns> public static string OpenFileName() { OpenFileName openFileName = new OpenFileName(); openFileName.structSize = Marshal.SizeOf(openFileName); openFileName.filter = "配置文件(*.txt)\0*.txt\0All Files\0*.*\0\0"; openFileName.file = new string(new char[256]); openFileName.maxFile = openFileName.file.Length; openFileName.fileTitle = new string(new char[64]); openFileName.maxFileTitle = openFileName.fileTitle.Length; openFileName.initialDir = Application.dataPath; // 默认路径 openFileName.title = "窗口标题"; // 注意 一下项目不一定要全选 但是0x00000008项不要缺少 // OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR openFileName.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008; if (DllLoadDialog.GetOpenFileName(openFileName)) { // Debug.LogFormat("OpenFileName file = {0} fileTitle = {1}", openFileName.file, openFileName.fileTitle); return openFileName.file; } return null; } /// <summary> /// 另存为对话框 /// </summary> /// <returns></returns> public static string SaveFileName() { OpenFileName openFileName = new OpenFileName(); openFileName.structSize = Marshal.SizeOf(openFileName); openFileName.filter = "配置文件(*.txt)\0*.txt\0All Files\0*.*\0\0"; openFileName.file = new string(new char[256]); openFileName.maxFile = openFileName.file.Length; openFileName.fileTitle = new string(new char[64]); openFileName.maxFileTitle = openFileName.fileTitle.Length; openFileName.initialDir = Application.dataPath;//默认路径 openFileName.title = "窗口标题"; // 注意 一下项目不一定要全选 但是0x00000008项不要缺少 // OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR openFileName.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008; if (DllLoadDialog.GetSaveFileName(openFileName)) { // Debug.LogFormat("SaveFileName file = {0} fileTitle = {1}", openFileName.file, openFileName.fileTitle); return openFileName.file; } return null; } public static string OpenFileDir() { OpenFileDir openFileDir = new OpenFileDir(); openFileDir.pszDisplayName = new string(new char[2000]); // 存放目录路径缓冲区 openFileDir.lpszTitle = "Open Project"; // 标题 //openFileDir.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX; // 新的样式,带编辑框 IntPtr pidlPtr = DllLoadDialog.SHBrowseForFolder(openFileDir); char[] charArray = new char[2000]; for (int i = 0; i < 2000; i++) { charArray[i] = '\0'; } DllLoadDialog.SHGetPathFromIDList(pidlPtr, charArray); string fullDirPath = new String(charArray); fullDirPath = fullDirPath.Substring(0, fullDirPath.IndexOf('\0')); // Debug.LogFormat("OpenFileDir = {0}", fullDirPath); return fullDirPath; } }
弹出窗的配置参数是通过我们声明的那个OPENFILENAME结构体来控制的,结构体的具体定义可以查看微软的网站:https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
最终效果:

PS:initialDir这个属性没有效果,每次打开的目录都是上次关闭的,第一次打开的目录也不是我设的地方,不知道是什么原因,不过不打算研究了,能用就行了
来自:https://blog.csdn.net/WPAPA/article/details/80538393