Unity3D llama rápida y eficientemente a la ventana del sistema en el lado de la PC, obtiene archivos locales y guarda archivos en el local

              Unity3D llama rápida y eficientemente a la ventana del sistema en el lado de la PC, obtiene archivos locales y guarda archivos en el local


Tabla de contenido

1. Introducción al blog

2. Contenido

(1) Visualización de efectos

(2) Método básico

3. Abra la ventana para obtener archivos locales.

4. Abra la ventana para guardar

5. Modularización de paquetes

6. Empuje

7. Conclusión


1. Introducción al blog

       Antes, hay funciones que necesitan llamar a la ventana del sistema de Windows en la PC para obtener o guardar los archivos localmente. Alguna información en Internet es similar, y básicamente son ajustadas por win32. Aquí hay una mejor manera. Aquí está la introducción , principalmente porque las de Internet no se han introducido en detalle, y no lo entiendo bien Aquí hay algunas breves introducciones, y finalmente las funciones están reunidas y etiquetadas como dll, lo cual es conveniente para uso futuro. Las funciones se agregarán y actualizarán gradualmente. Vaya a github, si está interesado, puede marcar y hacer un seguimiento.


2. Contenido

(1) Visualización de efectos

(2) Método básico

Primero coloquemos el código central y luego analicémoslo. Para aquellos de ustedes que están viendo, primero echen un vistazo al código a continuación y luego analícenlo después del código.

using System.Runtime.InteropServices;
using System;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class FileDialogData
{
    public int structSize = 0;                  //结构的内存大小
    public IntPtr dlgOwner = IntPtr.Zero;       //设置对话框的句柄
    public IntPtr instance = IntPtr.Zero;       //根据flags标志的设置,确定instance是谁的句柄,不设置则忽略
    public String filter = null;                //调取文件的过滤方式
    public String customFilter = null;          //一个静态缓冲区 用来保存用户选择的筛选器模式
    public int maxCustFilter = 0;               //缓冲区的大小
    public int filterIndex = 0;                 //指向的缓冲区包含定义过滤器的字符串对
    public String file = null;                  //存储调取文件路径
    public int maxFile = 0;                     //存储调取文件路径的最大长度 至少256
    public String fileTitle = null;             //调取的文件名带拓展名
    public int maxFileTitle = 0;                //调取文件名最大长度
    public String initialDir = null;            //最初目录
    public String title = null;                 //打开窗口的名字
    public int flags = 0;                       //初始化对话框的一组位标志  参数类型和作用查阅官方API
    public short fileOffset = 0;                //文件名前的长度
    public short fileExtension = 0;             //拓展名前的长度
    public String defExt = null;                //默认的拓展名
    public IntPtr custData = IntPtr.Zero;       //传递给lpfnHook成员标识的钩子子程的应用程序定义的数据
    public IntPtr hook = IntPtr.Zero;           //指向钩子的指针。除非Flags成员包含OFN_ENABLEHOOK标志,否则该成员将被忽略。
    public String templateName = null;          //模块中由hInstance成员标识的对话框模板资源的名称
    public IntPtr reservedPtr = IntPtr.Zero;
    public int reservedInt = 0;
    public int flagsEx = 0;                     //可用于初始化对话框的一组位标志
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenDialogData : FileDialogData
{

}

/*这是C#引用非托管的C/C++的DLL的一种定义定义结构体的方式,主要是为了内存中排序,LayoutKind有两个属性Sequential和Explicit

Sequential表示顺序存储,结构体内数据在内存中都是顺序存放的Explicit表示精确布局,需要用FieldOffset()设置每个成员的位置这都是

为了使用非托管的指针准备的,知道什么意思就行,C#的CLR提供了更为灵活的自动管理方式,所以对C#来说可有可无。

CharSet=CharSet.Ansi表示编码方式
*/
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class SaveDialogData : FileDialogData
{

}

public class OpenFileDialog
{
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetOpenFileName([In, Out] OpenDialogData ofd);
}
public class SaveFileDialog
{
    [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    public static extern bool GetSaveFileName([In, Out] SaveDialogData ofd);
}

 

       Nuestra idea central es usar C # para hacer referencia a Comdlg32.dll, un dll escrito en C ++ en Windows. Este dll es una biblioteca de clases para las ventanas del sistema en Windows. Para el método de referencia, usamos el método de [DllImport], que es el blogger. Hay una introducción en el artículo anterior. Si no lo sabe, puede omitir. También hay un portal al final de este artículo. No introduciré más aquí. También hay un método de definición [ StructLayout] en el código. Esta función está en la página anterior del blogger. También hay una introducción en esta entrada de blog. Si no sabes cómo saltar y echar un vistazo, esta función es principalmente para garantizar que el orden de la estructura de datos definida por nosotros no se verá afectada.

Núcleo 1 : FileDialogData, esta es una estructura de datos definida por nosotros. Por supuesto, no se define casualmente. Esta es una estructura de datos relacionada con la ventana en Comdlg32.dll. La estructura que definimos debe ser consistente con la estructura de datos en la biblioteca , que contiene Necesitamos la información relevante de la ventana. Parte de los datos que contiene se configuran de antemano antes de que abramos la ventana, y parte de ellos se asignará después de que obtengamos o guardemos el archivo local. He escrito todos los comentarios en el código anterior. Míralo, y si no lo entiendes, míralo en la explicación oficial a continuación.

Núcleo 2 : OpenDialogData, SaveDialogData Aquí nos dividimos en dos clases diferentes por herencia para facilitar la asignación de diferentes ventanas posteriormente.

Núcleo 3 : OpenFileDialog, SaveFileDialog Aquí, usamos C # para llamar al método C ++ en Comdlg32.dll a través de una referencia externa, y luego asignamos información relacionada con la ventana a la estructura de datos que definimos.

 

官方 API de C ++ : https://docs.microsoft.com/zh-cn/windows/win32/api/commdlg/ns-commdlg-openfilenamea


3. Abra la ventana para obtener archivos locales.

        提前赋值的数据 
     
        CustomOpenData = new OpenDialogData();
        CustomOpenData.structSize = Marshal.SizeOf(CustomOpenData);
        CustomOpenData.filter =  "All Files\0*.*\0\0";
        CustomOpenData.file = new string(new char[256]);
        CustomOpenData.maxFile = CustomOpenData.file.Length;
        CustomOpenData.fileTitle = new string(new char[1000]);
        CustomOpenData.maxFileTitle = CustomOpenData.fileTitle.Length;
        CustomOpenData.initialDir = Application.dataPath.Replace('/', '\\') + "\\aaa\\";
        CustomOpenData.title = "打开项目";
        CustomOpenData.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;

Nota : Aquí primero instanciamos un OpenDialogData, que es la estructura de datos que definimos previamente en base a la estructura de datos de C ++ en la biblioteca. Las propiedades asignadas de antemano no se introducen por separado aquí. Cada elemento del código anterior tiene comentarios. Puede ir y echa un vistazo.

    /// <summary>
    /// 打开窗口
    /// </summary>
    /// <returns></returns> 和该文件相关的数据
    public OpenDialogData OpenFileDlg()
    {
        if (OpenFileDialog.GetOpenFileName(CustomOpenData))
        {
            return CustomOpenData;
        }
        return null;
    }

Nota: Esto es lo más importante, es decir, este método abre la ventana. GetOpenFileName es un método C ++. Ingresamos la estructura de datos como parámetro. Si seleccionamos un archivo en la ventana abierta y lo abrimos, se devolverá CustomOpenData ejecutado. La estructura de datos asignada se devuelve. Si la ventana se cancela, devolverá nulo. Podemos ver el nombre del archivo, ruta, extensión, etc. del archivo seleccionado en CustomOpenData.

 


4. Abra la ventana para guardar

       Básicamente, no hay diferencia entre guardar y abrir. La diferencia es que la asignación inicial de la estructura de datos es algo diferente. Hay una extensión del archivo guardado defExt, y luego el método de llamada de C ++ es GetSaveFileName

        提前赋值的数据
       
        CustomSaveData = new SaveDialogData();
        CustomSaveData.structSize = Marshal.SizeOf(CustomSaveData);
        CustomSaveData.filter = "All files (*.*)|*.*";
        CustomSaveData.file = new string(new char[256]);
        CustomSaveData.maxFile = CustomSaveData.file.Length;
        CustomSaveData.fileTitle = new string(new char[64]);
        CustomSaveData.maxFileTitle = CustomSaveData.fileTitle.Length;
        CustomSaveData.initialDir = Application.dataPath.Replace('/', '\\') ;  // default path  
        CustomSaveData.title = "保存项目";
        CustomSaveData.defExt = "txt";
        CustomSaveData.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
    
    打开保存窗口的方法

    public SaveDialogData SaveFileDlg()
    {
        if (SaveFileDialog.GetSaveFileName(CustomSaveData))
        {
            return CustomSaveData;
        }
        return null;
    }

5. Modularización de paquetes

        De acuerdo con la idea central anterior, el blogger expandirá esta función y la etiquetará como Dll. Es más conveniente de usar. Es relativamente simple en la actualidad. El método de llamada es el siguiente. Los bloggers posteriores actualizarán gradualmente la función, como abrir directamente un texto o Json puede leer directamente datos internos y así sucesivamente. El dll y el código fuente están todos en github. Si está interesado, puede descargarlo.

    /// <summary>
    /// 打开本地文件
    /// </summary>
    public void OpenProject()
    {
        FileDialogMgr mgr = new FileDialogMgr();    //实例化窗口管理器
        mgr.SetFilteringWay(EnumFilteringWay.Png);  //设置过滤方式
        OpenDialogData mgrData = mgr.OpenFileDlg(); //获取本地文件的信息
    }
    /// <summary>
    /// 保存文件到本地
    /// </summary>
    public void SaveProject()
    {
        FileDialogMgr mgr = new FileDialogMgr();    //实例化窗口管理器
        mgr.SetFileExtension("txt");                //设置保存文件的后缀
        SaveDialogData mgrData = mgr.SaveFileDlg(); //获取保存文件的信息
    }

6. Empuje

github: https://github.com/KingSun5/FileDialogMgr

dllImport introducción: https://blog.csdn.net/Mr_Sun88/article/details/100626798

Introducción a StructLayout: https://blog.csdn.net/Mr_Sun88/article/details/101323222


7. Conclusión

       Si crees que el artículo del blogger está bien escrito, es mejor que prestes atención al blogger. Github hace clic en Destacar, destacar, destacar y le gusta la publicación del blog. La capacidad del blogger es limitada. Si hay algún error en el texto, por favor comente y critique.

       Grupo de intercambio QQ: 806091680 (Chinar)

       Este grupo fue creado por el blogger de CSDN Chinar, ¡lo recomiendo! ¡Yo también estoy en el grupo!

 

Supongo que te gusta

Origin blog.csdn.net/Mr_Sun88/article/details/100681423
Recomendado
Clasificación