unity調用操作系統的dialog

有個需求,就是在擴展編輯器功能時,有一些配置文件需要讀取,現在希望能選取這個東西,而不是每次手填地址。
找了半天unity提供的組件,發現沒有提供這個功能呀,這可怎麼辦???
突然想到unity用的是c#呀,那能不能直接使用c#的系統彈窗,想到就查,結果竟然還真的可以,下面我們來看看要怎麼搞。

參考的這個博客的內容:
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 這個屬性沒有效果,每次打開的目錄都是上次關閉的,第一次打開的目錄也不是我設的地方,不知道是什麼原因,不過不打算研究了,能用就行了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章