Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

OpenFileDialog in Runtime

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

  1. Astiolo

    Astiolo

    Joined:
    Dec 18, 2014
    Posts:
    27
    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;
    3.  
    4. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    5.  
    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. }
    31.  
    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.     }
    31.  
    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

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,722
    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

    Astiolo

    Joined:
    Dec 18, 2014
    Posts:
    27
    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

    bdovaz

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

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,645
    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

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,042
    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

    Tautvydas-Zilys

    Unity Technologies

    Joined:
    Jul 25, 2013
    Posts:
    10,645
    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

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,042
    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

    Astiolo

    Joined:
    Dec 18, 2014
    Posts:
    27
    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

    gkngkc

    Joined:
    Feb 4, 2013
    Posts:
    17
  11. avi9111

    avi9111

    Joined:
    Feb 24, 2016
    Posts:
    31

    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

    Astiolo

    Joined:
    Dec 18, 2014
    Posts:
    27
    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

    ZukoFire

    Joined:
    Apr 18, 2018
    Posts:
    2
    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...
    我真是中国人、、、绕了一圈发现原来CSDN上就解决了我的问题...坑爹啊!!
     
    jonaskgmoo likes this.
  14. Mad_26

    Mad_26

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

    Bshsf_9527

    Joined:
    Sep 6, 2017
    Posts:
    42
    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 https://stackoverflow.com/questions/4666580/how-can-i-set-topmost-at-the-savefiledialog-using-c#

    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;
    27.  
    28.     public FileOpenDialog()
    29.     {
    30.         dlgOwner = GetForegroundWindow();
    31.     }
    32.  
    33.     [DllImport("user32.dll")]
    34.     public static extern IntPtr GetForegroundWindow();
    35. }
     
  16. Mad_26

    Mad_26

    Joined:
    Apr 25, 2019
    Posts:
    15
    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

    BiomotionLab

    Joined:
    Oct 9, 2018
    Posts:
    11
  18. L4Z3RC47

    L4Z3RC47

    Joined:
    Jun 21, 2015
    Posts:
    46
    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

    none3d

    Joined:
    Mar 4, 2021
    Posts:
    168
    Thaina likes this.
  20. unity_zP4G898ky1jT3A

    unity_zP4G898ky1jT3A

    Joined:
    Mar 11, 2023
    Posts:
    26
    I needed it and OpenFileDialog is not working. What will we do now?

    hata.PNG
    WHY DONT WORK?

    Error:
    The type or namespace name 'OpenFileDialog' could not be found (are you missing a using directive or an assembly reference?)