Unity3Dは、PC側のシステムウィンドウをすばやく効率的に呼び出し、ローカルファイルを取得し、ファイルをローカルに保存します

              Unity3Dは、PC側のシステムウィンドウをすばやく効率的に呼び出し、ローカルファイルを取得し、ファイルをローカルに保存します


目次

1.ブログ紹介

2.コンテンツ

(1)エフェクト表示

(2)コア方式

3.ウィンドウを開いてローカルファイルを取得します

4.保存するウィンドウを開きます

5.パッケージのモジュール化

6.プッシュ

7.結論


1.ブログ紹介

       以前は、ファイルをローカルで取得または保存するためにPCのWindowsシステムウィンドウを呼び出す必要がある関数があります。インターネット上の一部の情報は類似しており、基本的にwin32によって調整されます。これがより良い方法です。これが紹介です。 、主にインターネット上のものが詳しく紹介されておらず、よくわからないためです。簡単な紹介をいくつか紹介し、最後に関数をまとめてdllとしてラベル付けします。これは、将来の使用に便利です。関数は徐々に追加および更新されます。githubにアクセスしてください。興味がある場合は、ブックマークしてフォローアップできます。


2.コンテンツ

(1)エフェクト表示

(2)コア方式

コアコードを最初に立てて分析してみましょう。見ている人は、まず以下のコードを見て、コードの後で分析してみましょう。

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);
}

 

       私たちのコアアイデアは、C#を使用してWindows上のC ++で記述されたdllであるComdlg32.dllを参照することです。このdllは、Windows上のシステムウィンドウ用のクラスライブラリです。参照メソッドには、[DllImport]のメソッドを使用します。ブロガー。前回の記事で紹介があります。わからない場合はスキップできます。この記事の最後にポータルもあります。ここではこれ以上紹介しません。定義方法もあります[コード内のStructLayout]。この機能はブロガーの前のページにあります。このブログ投稿にも紹介があります。ジャンプして確認する方法がわからない場合、この機能は主に次の順序を確認するためのものです。私たちが定義したデータ構造が中断されることはありません。

コア1:FileDialogData、これは私たちが定義したデータ構造です。もちろん、気軽に定義することはできません。これはComdlg32.dllのウィンドウ関連のデータ構造です。定義する構造は、ライブラリのデータ構造と一致している必要があります。ウィンドウの関連情報が必要です。ウィンドウを開く前にデータの一部を事前に設定し、ローカルファイルを取得または保存した後にデータの一部を割り当てます。すべてのコメントを書き込みました。上記のコードでそれを見てください、そしてあなたがそれを理解していないならば、それを以下の公式の説明から見てください。

コア2:OpenDialogData、SaveDialogDataここでは、後で異なるウィンドウを簡単に割り当てることができるように、継承によって2つの異なるクラスに分けられます。

コア3:OpenFileDialog、SaveFileDialogここでは、C#を使用して外部参照を介してComdlg32.dllのC ++メソッドを呼び出し、定義したデータ構造にウィンドウ関連の情報を割り当てます。

 

官方C ++ APIhttps//docs.microsoft.com/zh-cn/windows/win32/api/commdlg/ns-commdlg-openfilenamea


3.ウィンドウを開いてローカルファイルを取得します

        提前赋值的数据 
     
        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;

:ここでは、最初にOpenDialogDataをインスタンス化します。これは、ライブラリ内のC ++データ構造に基づいて以前に定義したデータ構造です。事前に割り当てられたプロパティはここでは個別に紹介されていません。上記のコードの各項目にはコメントがあります。見てみましょう。

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

注:これは最も重要なことです。つまり、このメソッドはウィンドウを開きます。GetOpenFileNameはC ++メソッドです。データ構造をパラメーターとして入力します。開いたウィンドウでファイルを選択して開くと、CustomOpenDataが返されます。割り当てられたデータ構造が返送されます。ウィンドウがキャンセルされると、nullが返されます。選択したファイルのファイル名、パス、拡張子などをCustomOpenDataで表示できます。

 


4.保存するウィンドウを開きます

       保存と開くの間に基本的な違いはありません。違いは、データ構造の最初の割り当てが多少異なることです。保存ファイルdefExtの拡張子があり、C ++で呼び出すメソッドは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.パッケージのモジュール化

        上記のコアアイデアに従って、ブロガーはこの関数を拡張してDllというラベルを付けます。使用する方が便利です。現在は比較的簡単です。呼び出し方法は次のとおりです。後続のブロガーは関数を徐々に更新します。テキストを直接開く、Jsonが内部データを直接読み取るなど、dllとソースコードはすべてgithubにあります。興味がある場合は、ダウンロードできます。

    /// <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.プッシュ

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

dllImportの紹介:https://blog.csdn.net/Mr_Sun88/article/details/100626798

StructLayoutの紹介:https://blog.csdn.net/Mr_Sun88/article/details/101323222


7.結論

       ブロガーの記事がうまく書かれていると思う場合は、ブロガーに注意を払うことをお勧めします。Githubは、スター、スター、スターをクリックし、ブログ投稿を高く評価します。ブロガーの能力は制限されています。テキストにエラーがある場合は、コメントして批判してください。

       QQ交換グループ:806091680(中国人)

       このグループは、CSDNブロガーのChinarによって作成されました。お勧めします。私もグループにいます!

 

おすすめ

転載: blog.csdn.net/Mr_Sun88/article/details/100681423