Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

OpenFileDialog in Runtime

Discussion in 'Windows' started by Astiolo, Mar 5, 2017.

  1. Astiolo


    Dec 18, 2014
    I spent quite a while searching for a way to open the Windows native open file dialog and eventually stumbled on some code that worked in a Chinese forum (I can't speak or read Chinese).

    First you will need this DllTest code:

    Code (CSharp):
    1. using System;
    2. using System.Runtime.InteropServices;
    4. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    6. public class OpenFileName {
    7.     public int      structSize = 0;
    8.     public IntPtr   dlgOwner = IntPtr.Zero;
    9.     public IntPtr   instance = IntPtr.Zero;
    10.     public String   filter = null;
    11.     public String   customFilter = null;
    12.     public int      maxCustFilter = 0;
    13.     public int      filterIndex = 0;
    14.     public String   file = null;
    15.     public int      maxFile = 0;
    16.     public String   fileTitle = null;
    17.     public int      maxFileTitle = 0;
    18.     public String   initialDir = null;
    19.     public String   title = null;
    20.     public int      flags = 0;
    21.     public short    fileOffset = 0;
    22.     public short    fileExtension = 0;
    23.     public String   defExt = null;
    24.     public IntPtr   custData = IntPtr.Zero;
    25.     public IntPtr   hook = IntPtr.Zero;
    26.     public String   templateName = null;
    27.     public IntPtr   reservedPtr = IntPtr.Zero;
    28.     public int      reservedInt = 0;
    29.     public int      flagsEx = 0;
    30. }
    32. public class DllTest {
    33.     [DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
    34.     public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
    35.     public static bool GetOpenFileName1([In, Out] OpenFileName ofn) {
    36.         return GetOpenFileName(ofn);
    37.     }
    38. }
    Then you can open the dialog with the following code (using System.Runtime.InteropServices):

    Code (CSharp):
    1. OpenFileName ofn = new OpenFileName();
    2.         ofn.structSize = Marshal.SizeOf(ofn);
    3.         ofn.filter = "All Files\0*.*\0\0";
    4.         ofn.file = new string(new char[256]);
    5.         ofn.maxFile = ofn.file.Length;
    6.         ofn.fileTitle = new string(new char[64]);
    7.         ofn.maxFileTitle = ofn.fileTitle.Length;
    8.         ofn.initialDir = UnityEngine.Application.dataPath;
    9.         ofn.title = "Upload Image";
    10.         ofn.defExt = "PNG";
    11.         ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR
    12.         if(DllTest.GetOpenFileName(ofn)) {
    13.             FileDialogResult("file:///" + ofn.file);
    14.         }
    Where "FileDialogResult" is just a function created to act on the returned file path. Depending on your application, you will probably want to adjust some of the parameters like the file extension and title. I don't really understand this code though, it's just something I found that worked for me so I probably won't be able to help if you run into problems.

    Here is the original forum and the following the their test code for opening the dialog and applying the loaded image as a texture. Just put it on an object in the scene and assign the 'plane' object (I thought I should include it just to make it a little easier for you to make sure it works).

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Text;
    4. using System.Runtime.InteropServices;
    5. using System;
    6. public class Test : MonoBehaviour {
    7.     public GameObject plane;
    8.     void OnGUI()
    9.     {
    10.         if(GUI.Button(new Rect(0,0,100,35),"OpenDialog"))
    11.         {
    12.             OpenFileName ofn = new OpenFileName();
    13.             ofn.structSize = Marshal.SizeOf(ofn);
    14.             ofn.filter = "All Files\0*.*\0\0";
    15.             ofn.file = new string(new char[256]);
    16.             ofn.maxFile = ofn.file.Length;
    17.             ofn.fileTitle = new string(new char[64]);
    18.             ofn.maxFileTitle = ofn.fileTitle.Length;
    19.             ofn.initialDir =UnityEngine.Application.dataPath;//默认路径
    20.             ofn.title = "Open Project";
    21.             ofn.defExt = "JPG";//显示文件的类型
    22.            //注意 一下项目不一定要全选 但是0x00000008项不要缺少
    23.             ofn.flags=0x00080000|0x00001000|0x00000800|0x00000200|0x00000008;//OFN_EXPLORER|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST| OFN_ALLOWMULTISELECT|OFN_NOCHANGEDIR
    24.             if(DllTest.GetOpenFileName( ofn ))
    25.             {
    26.                 StartCoroutine(WaitLoad(ofn.file));//加载图片到panle
    27.                 Debug.Log( "Selected file with full path: {0}"+ofn.file );
    28.             }
    29.         }
    30.     }
    32.     IEnumerator WaitLoad(string fileName)
    33.     {
    34.         WWW wwwTexture=new WWW("file://"+fileName);
    35.         Debug.Log(wwwTexture.url);
    36.         yield return wwwTexture;
    37.         plane.renderer.material.mainTexture=wwwTexture.texture;
    38.     }
    39. }
    Please share any improvements and it would be fantastic to add some multi platform support but I'll be looking into that later on.
    nlesommer and Marrt like this.
  2. Aurimas-Cernius


    Unity Technologies

    Jul 31, 2013
    GetOpenFileName() is Windows function for opening that dialog. What you do here is define a C# struct with marshaling so that when you call this Windows function it gets transformed into C struct that function takes as an argument. You can find full documentation about that function in Microsofts website.
    As for multi platform it is much more complicated. Other OSes have their own native APIs for such dialog and those APIs are very different, so making a generic platform independent API for this is quite a challenge.
  3. Astiolo


    Dec 18, 2014
    To be honest I think this should be something built into Unity. It's in the Editor as a simple function, why not include that as an option in runtime?
  4. bdovaz


    Dec 10, 2011
    I agree, If there is an editor API for this why would not expose it for runtime?
  5. Tautvydas-Zilys


    Unity Technologies

    Jul 25, 2013
    Implementing it on 3 platforms is easier than implementing it on 20+. Plus, hardly any games need this functionality.
    theolagendijk and Rafarel like this.
  6. bdovaz


    Dec 10, 2011
    I mean in desktop platforms (windows, osx, Linux) because on other platforms like mobiles platforms is not always possible or have sense (consoles...). In Android 4.4+ was added that features and on iOS you can only select images or videos you can't browse freely any file.

    For simple features like this would be easier if Unity was open source and people would develop and pull request this things that are not a priority for Unity.
  7. Tautvydas-Zilys


    Unity Technologies

    Jul 25, 2013
    You don't need Unity's source code to implement anything like this. People can and have extended the engine through using our plugin model. There are loads of plugins on the asset store...

    If you think this is important, you can always make a plugin yourself and put it out there :).
    theolagendijk and LW like this.
  8. bdovaz


    Dec 10, 2011
    You haven't understand it. I know I can do it myself without source code. I have developed many Plugins on different platforms.

    I meant that having source code and making pull-requests we could make it to core and Unity staff focus on other more important things.
  9. Astiolo


    Dec 18, 2014
    Sure, but why not have that option for those three platforms?

    That's a terrible philosophy for creating good software and it frustrates me a lot when I find simple things that Unity should have but instead I have to pay someone else to get their fix. I understand you can't provide everything that gets requested but some things should just be part of the engine. For some examples there's this functionality, a decent control mapping system (like rewired), the ability to instantiate prefabs with lightmap data, etc.

    Just to be clear I'm not saying the asset store is a bad idea. Just that you shouldn't go telling your customers to do the work for you, to overcome simple limitations of your software. When those features should have just been implemented in the engine in the first place.
    Last edited: Mar 14, 2017
  10. gkngkc


    Feb 4, 2013
  11. avi9111


    Feb 24, 2016

    Thanks for your providede code. I got this, and I have to figure out it, although it seems that the open function is OK, but still got these words

    (balabala .......working dirctor was changd from.........set it back..........after you are done)
  12. Astiolo


    Dec 18, 2014
    I believe that happens when you click back to unity while the file dialogue is still open. I'm not sure how to fix that.
  13. ZukoFire


    Apr 18, 2018
    ok, is really help to me, but im a Chinese, and in fact...o_Obefore i find your invitation, i already read this gay's invitation......:rolleyes:at that time, i dont understand...
    jonaskgmoo likes this.
  14. Mad_26


    Apr 25, 2019
    Can we save the file in the form of pdf in unity3d?
  15. Bshsf_9527


    Sep 6, 2017
    I find the way to make the dialog show at top most.
    this is the reference :
    winforms - How can I set topmost at the SaveFileDialog using C#? - Stack Overflow

    and this is the point:
    Code (CSharp):
    1. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    2. public class FileOpenDialog
    3. {
    4.     public int structSize = 0;
    5.     public IntPtr dlgOwner = IntPtr.Zero;
    6.     public IntPtr instance = IntPtr.Zero;
    7.     public String filter = null;
    8.     public String customFilter = null;
    9.     public int maxCustFilter = 0;
    10.     public int filterIndex = 0;
    11.     public String file = null;
    12.     public int maxFile = 0;
    13.     public String fileTitle = null;
    14.     public int maxFileTitle = 0;
    15.     public String initialDir = null;
    16.     public String title = null;
    17.     public int flags = 0;
    18.     public short fileOffset = 0;
    19.     public short fileExtension = 0;
    20.     public String defExt = null;
    21.     public IntPtr custData = IntPtr.Zero;
    22.     public IntPtr hook = IntPtr.Zero;
    23.     public String templateName = null;
    24.     public IntPtr reservedPtr = IntPtr.Zero;
    25.     public int reservedInt = 0;
    26.     public int flagsEx = 0;
    28.     public FileOpenDialog()
    29.     {
    30.         dlgOwner = GetForegroundWindow();
    31.     }
    33.     [DllImport("user32.dll")]
    34.     public static extern IntPtr GetForegroundWindow();
    35. }
  16. Mad_26


    Apr 25, 2019
    I know I am posting offtopic question here , since i was unable to find any post regarding the sharp pdf with unity3d I am using the sharp pdf package with unity3d and i am facing difficulties for windows platform like: 1. How to dynamically increase the column height according to the text size at runtime. 2. How do i insert an image without using the co-routine function. 3. How to dynamically write the data on the new page if current page is filled and data is still pending. For example, there are 50 rows in my table at runtime and one first page 30rows occupy the space, then how do i dynamically write the remaining 20 rows on second page. 4. Instead of storing the file in root folder, in assets folder , how can i store the pdf at different location by selecting the folder from the system.

    Can anyone please help me out, it would be great help....Thank you in advance.
  17. BiomotionLab


    Oct 9, 2018
  18. L4Z3RC47


    Jun 21, 2015
    This is pretty great. I would love something like this for drag and drop capabilities as well but haven't had the time to write something myself yet :p
  19. none3d


    Mar 4, 2021