Unity打开本地文件(不使用dll的情况下)

更全的链接:Unity 选择本地目录选择文件打开指定文件夹(无需引入dll)_love and share-CSDN博客https://blog.csdn.net/qq_39342142/article/details/103781728

比较适合的内容:

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一样的问题

发布没有测试,如果有发布测试之后有不同反应的,可以评论留言

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值