-
Notifications
You must be signed in to change notification settings - Fork 0
/
nativefiledialog.cs
150 lines (127 loc) · 4.64 KB
/
nativefiledialog.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System;
using System.Runtime.InteropServices;
using System.Text;
public static class nativefiledialog
{
public enum nfdresult_t
{
NFD_ERROR,
NFD_OKAY,
NFD_CANCEL
}
public struct nfdpathset_t
{
private IntPtr buf;
private IntPtr indices;
private IntPtr count;
}
private const string nativeLibName = "nfd";
private static int Utf8Size(string str)
{
return str.Length * 4 + 1;
}
private unsafe static byte* Utf8EncodeNullable(string str)
{
if (str == null)
{
return null;
}
int num = Utf8Size(str);
byte* ptr = (byte*)(void*)Marshal.AllocHGlobal(num);
fixed (char* chars = str)
{
Encoding.UTF8.GetBytes(chars, (str != null) ? (str.Length + 1) : 0, ptr, num);
}
return ptr;
}
private unsafe static string UTF8_ToManaged(IntPtr s, bool freePtr = false)
{
if (s == IntPtr.Zero)
{
return null;
}
byte* ptr;
for (ptr = (byte*)(void*)s; *ptr != 0; ptr++)
{
}
int num = (int)(ptr - (byte*)(void*)s);
if (num == 0)
{
return string.Empty;
}
char* ptr2 = stackalloc char[num];
int chars = Encoding.UTF8.GetChars((byte*)(void*)s, num, ptr2, num);
string result = new string(ptr2, 0, chars);
if (freePtr)
{
free(s);
}
return result;
}
[DllImport("msvcrt", CallingConvention = CallingConvention.Cdecl)]
private static extern void free(IntPtr ptr);
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_OpenDialog")]
private unsafe static extern nfdresult_t INTERNAL_NFD_OpenDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
public unsafe static nfdresult_t NFD_OpenDialog(string filterList, string defaultPath, out string outPath)
{
byte* intPtr = Utf8EncodeNullable(filterList);
byte* ptr = Utf8EncodeNullable(defaultPath);
IntPtr outPath2;
nfdresult_t result = INTERNAL_NFD_OpenDialog(intPtr, ptr, out outPath2);
Marshal.FreeHGlobal((IntPtr)intPtr);
Marshal.FreeHGlobal((IntPtr)ptr);
outPath = UTF8_ToManaged(outPath2, freePtr: true);
return result;
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_OpenDialogMultiple")]
private unsafe static extern nfdresult_t INTERNAL_NFD_OpenDialogMultiple(byte* filterList, byte* defaultPath, out nfdpathset_t outPaths);
public unsafe static nfdresult_t NFD_OpenDialogMultiple(string filterList, string defaultPath, out nfdpathset_t outPaths)
{
byte* intPtr = Utf8EncodeNullable(filterList);
byte* ptr = Utf8EncodeNullable(defaultPath);
nfdresult_t result = INTERNAL_NFD_OpenDialogMultiple(intPtr, ptr, out outPaths);
Marshal.FreeHGlobal((IntPtr)intPtr);
Marshal.FreeHGlobal((IntPtr)ptr);
return result;
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_SaveDialog")]
private unsafe static extern nfdresult_t INTERNAL_NFD_SaveDialog(byte* filterList, byte* defaultPath, out IntPtr outPath);
public unsafe static nfdresult_t NFD_SaveDialog(string filterList, string defaultPath, out string outPath)
{
byte* intPtr = Utf8EncodeNullable(filterList);
byte* ptr = Utf8EncodeNullable(defaultPath);
IntPtr num;
nfdresult_t ptr2 = INTERNAL_NFD_SaveDialog(intPtr, ptr, out num);
Marshal.FreeHGlobal((IntPtr)intPtr);
Marshal.FreeHGlobal((IntPtr)ptr);
outPath = UTF8_ToManaged(num, freePtr: true);
return ptr2;
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_PickFolder")]
private unsafe static extern nfdresult_t INTERNAL_NFD_PickFolder(byte* defaultPath, out IntPtr outPath);
public unsafe static nfdresult_t NFD_PickFolder(string defaultPath, out string outPath)
{
byte* intPtr = Utf8EncodeNullable(defaultPath);
IntPtr outPath2;
nfdresult_t result = INTERNAL_NFD_PickFolder(intPtr, out outPath2);
Marshal.FreeHGlobal((IntPtr)intPtr);
outPath = UTF8_ToManaged(outPath2, freePtr: true);
return result;
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_GetError")]
private static extern IntPtr INTERNAL_NFD_GetError();
public static string NFD_GetError()
{
return UTF8_ToManaged(INTERNAL_NFD_GetError());
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr NFD_PathSet_GetCount(ref nfdpathset_t pathset);
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl, EntryPoint = "NFD_PathSet_GetPath")]
private static extern IntPtr INTERNAL_NFD_PathSet_GetPath(ref nfdpathset_t pathset, IntPtr index);
public static string NFD_PathSet_GetPath(ref nfdpathset_t pathset, IntPtr index)
{
return UTF8_ToManaged(INTERNAL_NFD_PathSet_GetPath(ref pathset, index));
}
[DllImport("nfd", CallingConvention = CallingConvention.Cdecl)]
public static extern void NFD_PathSet_Free(ref nfdpathset_t pathset);
}