![]() |
|
Native file dialog patch |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
NiteHackr brought up a bug in the native file dialog on Windows in this thread : I said I would work on it and I finally got time to do it. The problem was that lpstrFile wasn't being initialized (which prevented you from specifying the open/save file), and lpstrInitialDir was being initialized with a file path and not a folder. This is a very hacky fix, but it works, and it gives you the idea. I'm not aware of the conventions for handling strings in allegro internals so this is the way I did it. Here's the diff for win_dialog.c : 1
2c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>diff -u win_dialog.c win_dialog.new.c
3--- win_dialog.c 2014-12-22 18:37:54.191842600 -0600
4+++ win_dialog.new.c 2014-12-22 18:41:30.428979100 -0600
5@@ -8,6 +8,8 @@
6 *
7 */
8
9+#include <stdio.h>
10+
11 #include "allegro5/allegro.h"
12 #include "allegro5/allegro_native_dialog.h"
13 #include "allegro5/internal/aintern.h"
14@@ -141,8 +143,10 @@
15 OPENFILENAME ofn;
16 ALLEGRO_DISPLAY_WIN *win_display;
17 int flags = 0;
18+ int count = 0;
19 bool ret;
20 char buf[4096] = "";
21+ char dirbuf[4096] = "";
22 ALLEGRO_USTR *filter_string = NULL;
23
24 win_display = (ALLEGRO_DISPLAY_WIN *)display;
25@@ -170,8 +174,20 @@
26 ofn.nMaxFile = sizeof(buf);
27
28 if (fd->fc_initial_path) {
29- ofn.lpstrInitialDir =
30- al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
31+
32+ strcpy(buf , al_path_cstr((fd->fc_initial_path) , ALLEGRO_NATIVE_PATH_SEP));
33+
34+ // this is wrong - fc_initial_path holds the filename, not the base dir
35+ for (count = 0 ; count < al_get_path_num_components(fd->fc_initial_path) ; ++count) {
36+ char* dirpath = &dirbuf[0];
37+ int n = 0;
38+ const char* path_comp = al_get_path_component(fd->fc_initial_path , count);
39+ sprintf(dirpath , "%s%c%n" , path_comp , ALLEGRO_NATIVE_PATH_SEP , &n);
40+ dirpath += n;
41+ }
42+
43+ ofn.lpstrInitialDir = dirbuf;
44+// al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
45 }
46
47 if (fd->title)
48
49c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>
And here's the full al_show_native_file_dialog with the changes made to it so you can see more easily what is different. Whatever changes you wanna make are fine. I'm sure it will need to be edited before being accepted. 139
140bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
141 ALLEGRO_NATIVE_DIALOG *fd)
142{
143 OPENFILENAME ofn;
144 ALLEGRO_DISPLAY_WIN *win_display;
145 int flags = 0;
146 int count = 0;
147 bool ret;
148 char buf[4096] = "";
149 char dirbuf[4096] = "";
150 ALLEGRO_USTR *filter_string = NULL;
151
152 win_display = (ALLEGRO_DISPLAY_WIN *)display;
153
154 if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) {
155 return select_folder(win_display, fd);
156 }
157
158 /* Selecting a file. */
159 memset(&ofn, 0, sizeof(OPENFILENAME));
160 ofn.lStructSize = sizeof(OPENFILENAME);
161 ofn.hwndOwner = (win_display) ? win_display->window : NULL;
162
163 /* Create filter string. */
164 if (fd->fc_patterns) {
165 filter_string = create_filter_string(fd->fc_patterns);
166 ofn.lpstrFilter = al_cstr(filter_string);
167 }
168 else {
169 /* List all files by default. */
170 ofn.lpstrFilter = "All Files\0*.*\0\0";
171 }
172
173 ofn.lpstrFile = buf;
174 ofn.nMaxFile = sizeof(buf);
175
176 if (fd->fc_initial_path) {
177
178 strcpy(buf , al_path_cstr((fd->fc_initial_path) , ALLEGRO_NATIVE_PATH_SEP));
179
180 // this is wrong - fc_initial_path holds the filename, not the base dir
181 for (count = 0 ; count < al_get_path_num_components(fd->fc_initial_path) ; ++count) {
182 char* dirpath = &dirbuf[0];
183 int n = 0;
184 const char* path_comp = al_get_path_component(fd->fc_initial_path , count);
185 sprintf(dirpath , "%s%c%n" , path_comp , ALLEGRO_NATIVE_PATH_SEP , &n);
186 dirpath += n;
187 }
188
189 ofn.lpstrInitialDir = dirbuf;
190// al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
191 }
192
193 if (fd->title)
194 ofn.lpstrTitle = al_cstr(fd->title);
195
196 flags |= OFN_NOCHANGEDIR | OFN_EXPLORER;
197 if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) {
198 flags |= OFN_OVERWRITEPROMPT;
199 }
200 else {
201 flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0;
202 }
203 flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0;
204 flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN
205 ofn.Flags = flags;
206
207 if (flags & OFN_OVERWRITEPROMPT) {
208 ret = GetSaveFileName(&ofn);
209 }
210 else {
211 ret = GetOpenFileName(&ofn);
212 }
213
214 al_ustr_free(filter_string);
215
216 if (!ret) {
217 DWORD err = GetLastError();
218 if (err != ERROR_SUCCESS) {
219 char buf[1000];
220 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL);
221 ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", buf);
222 }
223 return false;
224 }
225
226 if (flags & OFN_ALLOWMULTISELECT) {
227 int i;
228 /* Count number of file names in buf. */
229 fd->fc_path_count = 0;
230 i = skip_nul_terminated_string(buf);
231 while (1) {
232 if (buf[i] == '\0') {
233 fd->fc_path_count++;
234 if (buf[i+1] == '\0')
235 break;
236 }
237 i++;
238 }
239 }
240 else {
241 fd->fc_path_count = 1;
242 }
243
244 if (fd->fc_path_count == 1) {
245 fd->fc_paths = al_malloc(sizeof(void *));
246 fd->fc_paths[0] = al_create_path(buf);
247 }
248 else {
249 int i, p;
250 /* If multiple files were selected, the first string in buf is the
251 * directory name, followed by each of the file names terminated by NUL.
252 */
253 fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *));
254 i = skip_nul_terminated_string(buf);
255 for (p = 0; p < (int)fd->fc_path_count; p++) {
256 fd->fc_paths[p] = al_create_path_for_directory(buf);
257 al_set_path_filename(fd->fc_paths[p], buf+i);
258 i += skip_nul_terminated_string(buf+i);
259 }
260 }
261
262 return true;
263}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Trent Gamblin
Member #261
April 2000
![]() |
Could you change this to use al_remove_path_component? EDIT: nvm, only removes directories... EDIT2: Try al_set_path_filename with NULL.
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Trent Gamblin said: Try al_set_path_filename with NULL. Okay, it works. Just have to keep in mind the file name has been erased from fc_initial_path for future reference. Here's the new diff : 1c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>diff -u win_dialog.old.c win_dialog.c
2--- win_dialog.old.c 2014-12-22 18:37:54.191842600 -0600
3+++ win_dialog.c 2014-12-22 22:44:16.880748300 -0600
4@@ -17,6 +17,8 @@
5
6 #include "allegro5/allegro_windows.h"
7
8+#include <string.h>
9+
10 /* We use RichEdit by default. */
11 #include <richedit.h>
12 #include <shlobj.h> // for folder selector
13@@ -142,9 +144,12 @@
14 ALLEGRO_DISPLAY_WIN *win_display;
15 int flags = 0;
16 bool ret;
17- char buf[4096] = "";
18+ const int BUFSIZE = 4096;
19+ char buf[BUFSIZE];
20 ALLEGRO_USTR *filter_string = NULL;
21
22+ buf[0] = '\0';
23+
24 win_display = (ALLEGRO_DISPLAY_WIN *)display;
25
26 if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) {
27@@ -166,12 +171,15 @@
28 ofn.lpstrFilter = "All Files\0*.*\0\0";
29 }
30
31+ /* Provide buffer for file chosen by dialog. */
32 ofn.lpstrFile = buf;
33 ofn.nMaxFile = sizeof(buf);
34
35+ /* Initialize file name buffer and starting directory */
36 if (fd->fc_initial_path) {
37- ofn.lpstrInitialDir =
38- al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
39+ strncpy(buf , al_path_cstr(fd->fc_initial_path , ALLEGRO_NATIVE_PATH_SEP) , BUFSIZE - 1);
40+ al_set_path_filename(fd->fc_initial_path , NULL);
41+ ofn.lpstrInitialDir = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
42 }
43
44 if (fd->title)
45
46c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>
And the function : 140bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
141 ALLEGRO_NATIVE_DIALOG *fd)
142{
143 OPENFILENAME ofn;
144 ALLEGRO_DISPLAY_WIN *win_display;
145 int flags = 0;
146 bool ret;
147 const int BUFSIZE = 4096;
148 char buf[BUFSIZE];
149 ALLEGRO_USTR *filter_string = NULL;
150
151 buf[0] = '\0';
152
153 win_display = (ALLEGRO_DISPLAY_WIN *)display;
154
155 if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) {
156 return select_folder(win_display, fd);
157 }
158
159 /* Selecting a file. */
160 memset(&ofn, 0, sizeof(OPENFILENAME));
161 ofn.lStructSize = sizeof(OPENFILENAME);
162 ofn.hwndOwner = (win_display) ? win_display->window : NULL;
163
164 /* Create filter string. */
165 if (fd->fc_patterns) {
166 filter_string = create_filter_string(fd->fc_patterns);
167 ofn.lpstrFilter = al_cstr(filter_string);
168 }
169 else {
170 /* List all files by default. */
171 ofn.lpstrFilter = "All Files\0*.*\0\0";
172 }
173
174 /* Provide buffer for file chosen by dialog. */
175 ofn.lpstrFile = buf;
176 ofn.nMaxFile = sizeof(buf);
177
178 /* Initialize file name buffer and starting directory */
179 if (fd->fc_initial_path) {
180 strncpy(buf , al_path_cstr(fd->fc_initial_path , ALLEGRO_NATIVE_PATH_SEP) , BUFSIZE - 1);
181 al_set_path_filename(fd->fc_initial_path , NULL);
182 ofn.lpstrInitialDir = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
183 }
184
185 if (fd->title)
186 ofn.lpstrTitle = al_cstr(fd->title);
187
188 flags |= OFN_NOCHANGEDIR | OFN_EXPLORER;
189 if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) {
190 flags |= OFN_OVERWRITEPROMPT;
191 }
192 else {
193 flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0;
194 }
195 flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0;
196 flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN
197 ofn.Flags = flags;
198
199 if (flags & OFN_OVERWRITEPROMPT) {
200 ret = GetSaveFileName(&ofn);
201 }
202 else {
203 ret = GetOpenFileName(&ofn);
204 }
205
206 al_ustr_free(filter_string);
207
208 if (!ret) {
209 DWORD err = GetLastError();
210 if (err != ERROR_SUCCESS) {
211 char buf[1000];
212 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL);
213 ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", buf);
214 }
215 return false;
216 }
217
218 if (flags & OFN_ALLOWMULTISELECT) {
219 int i;
220 /* Count number of file names in buf. */
221 fd->fc_path_count = 0;
222 i = skip_nul_terminated_string(buf);
223 while (1) {
224 if (buf[i] == '\0') {
225 fd->fc_path_count++;
226 if (buf[i+1] == '\0')
227 break;
228 }
229 i++;
230 }
231 }
232 else {
233 fd->fc_path_count = 1;
234 }
235
236 if (fd->fc_path_count == 1) {
237 fd->fc_paths = al_malloc(sizeof(void *));
238 fd->fc_paths[0] = al_create_path(buf);
239 }
240 else {
241 int i, p;
242 /* If multiple files were selected, the first string in buf is the
243 * directory name, followed by each of the file names terminated by NUL.
244 */
245 fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *));
246 i = skip_nul_terminated_string(buf);
247 for (p = 0; p < (int)fd->fc_path_count; p++) {
248 fd->fc_paths[p] = al_create_path_for_directory(buf);
249 al_set_path_filename(fd->fc_paths[p], buf+i);
250 i += skip_nul_terminated_string(buf+i);
251 }
252 }
253
254 return true;
255}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Trent Gamblin
Member #261
April 2000
![]() |
Not sure this is going to work. Shouldn't it check if it's an OPEN dialog before trimming the filename? After all if it's a SAVE dialog you want the filename right?
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Well you don't need it. Unless someone tried to re-use a file dialog. We could clone a path, discard the filename, set the directory and then discard the clone after calling GetOpenFileName. Because you don't want the filename in the string for the directory in open or save dialogs. New patch using a clone of the directory and checking for an empty filename to respect the documentation that states when the path ends with a directory separator then the filename is not specified, but the starting directory is : 1
2c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>diff -u win_dialog.old.c win_dialog.c
3--- win_dialog.old.c 2014-12-22 18:37:54.191842600 -0600
4+++ win_dialog.c 2014-12-23 12:51:26.442877800 -0600
5@@ -17,6 +17,8 @@
6
7 #include "allegro5/allegro_windows.h"
8
9+#include <string.h>
10+
11 /* We use RichEdit by default. */
12 #include <richedit.h>
13 #include <shlobj.h> // for folder selector
14@@ -142,8 +144,12 @@
15 ALLEGRO_DISPLAY_WIN *win_display;
16 int flags = 0;
17 bool ret;
18- char buf[4096] = "";
19+ const int BUFSIZE = 4096;
20+ char buf[BUFSIZE];
21 ALLEGRO_USTR *filter_string = NULL;
22+ ALLEGRO_PATH* initial_dir_path = 0;
23+
24+ buf[0] = '\0';
25
26 win_display = (ALLEGRO_DISPLAY_WIN *)display;
27
28@@ -166,12 +172,24 @@
29 ofn.lpstrFilter = "All Files\0*.*\0\0";
30 }
31
32+ /* Provide buffer for file chosen by dialog. */
33 ofn.lpstrFile = buf;
34 ofn.nMaxFile = sizeof(buf);
35
36+ /* Initialize file name buffer and starting directory */
37 if (fd->fc_initial_path) {
38- ofn.lpstrInitialDir =
39- al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
40+
41+ /* Respect an empty filename */
42+ if (strlen(al_get_path_filename(fd->fc_initial_path)) > 0) {
43+ strncpy(buf , al_path_cstr(fd->fc_initial_path , ALLEGRO_NATIVE_PATH_SEP) , BUFSIZE - 1);
44+ }
45+
46+ /* Clone the directory */
47+ initial_dir_path = al_clone_path(fd->fc_initial_path);
48+ if (initial_dir_path) {
49+ al_set_path_filename(initial_dir_path , NULL);
50+ ofn.lpstrInitialDir = al_path_cstr(initial_dir_path, ALLEGRO_NATIVE_PATH_SEP);
51+ }
52 }
53
54 if (fd->title)
55@@ -194,6 +212,10 @@
56 else {
57 ret = GetOpenFileName(&ofn);
58 }
59+
60+ if (initial_dir_path) {
61+ al_destroy_path(initial_dir_path);
62+ }
63
64 al_ustr_free(filter_string);
65
66
67c:\mingw\LIBS\A5GIT\allegro\addons\native_dialog>
1
2bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
3 ALLEGRO_NATIVE_DIALOG *fd)
4{
5 OPENFILENAME ofn;
6 ALLEGRO_DISPLAY_WIN *win_display;
7 int flags = 0;
8 bool ret;
9 const int BUFSIZE = 4096;
10 char buf[BUFSIZE];
11 ALLEGRO_USTR *filter_string = NULL;
12 ALLEGRO_PATH* initial_dir_path = 0;
13
14 buf[0] = '\0';
15
16 win_display = (ALLEGRO_DISPLAY_WIN *)display;
17
18 if (fd->flags & ALLEGRO_FILECHOOSER_FOLDER) {
19 return select_folder(win_display, fd);
20 }
21
22 /* Selecting a file. */
23 memset(&ofn, 0, sizeof(OPENFILENAME));
24 ofn.lStructSize = sizeof(OPENFILENAME);
25 ofn.hwndOwner = (win_display) ? win_display->window : NULL;
26
27 /* Create filter string. */
28 if (fd->fc_patterns) {
29 filter_string = create_filter_string(fd->fc_patterns);
30 ofn.lpstrFilter = al_cstr(filter_string);
31 }
32 else {
33 /* List all files by default. */
34 ofn.lpstrFilter = "All Files\0*.*\0\0";
35 }
36
37 /* Provide buffer for file chosen by dialog. */
38 ofn.lpstrFile = buf;
39 ofn.nMaxFile = sizeof(buf);
40
41 /* Initialize file name buffer and starting directory */
42 if (fd->fc_initial_path) {
43
44 /* Respect an empty filename */
45 if (strlen(al_get_path_filename(fd->fc_initial_path)) > 0) {
46 strncpy(buf , al_path_cstr(fd->fc_initial_path , ALLEGRO_NATIVE_PATH_SEP) , BUFSIZE - 1);
47 }
48
49 /* Clone the directory */
50 initial_dir_path = al_clone_path(fd->fc_initial_path);
51 if (initial_dir_path) {
52 al_set_path_filename(initial_dir_path , NULL);
53 ofn.lpstrInitialDir = al_path_cstr(initial_dir_path, ALLEGRO_NATIVE_PATH_SEP);
54 }
55 }
56
57 if (fd->title)
58 ofn.lpstrTitle = al_cstr(fd->title);
59
60 flags |= OFN_NOCHANGEDIR | OFN_EXPLORER;
61 if (fd->flags & ALLEGRO_FILECHOOSER_SAVE) {
62 flags |= OFN_OVERWRITEPROMPT;
63 }
64 else {
65 flags |= (fd->flags & ALLEGRO_FILECHOOSER_FILE_MUST_EXIST) ? OFN_FILEMUSTEXIST : 0;
66 }
67 flags |= (fd->flags & ALLEGRO_FILECHOOSER_MULTIPLE) ? OFN_ALLOWMULTISELECT : 0;
68 flags |= (fd->flags & ALLEGRO_FILECHOOSER_SHOW_HIDDEN) ? 0x10000000 : 0; // NOTE: 0x10000000 is FORCESHOWHIDDEN
69 ofn.Flags = flags;
70
71 if (flags & OFN_OVERWRITEPROMPT) {
72 ret = GetSaveFileName(&ofn);
73 }
74 else {
75 ret = GetOpenFileName(&ofn);
76 }
77
78 if (initial_dir_path) {
79 al_destroy_path(initial_dir_path);
80 }
81
82 al_ustr_free(filter_string);
83
84 if (!ret) {
85 DWORD err = GetLastError();
86 if (err != ERROR_SUCCESS) {
87 char buf[1000];
88 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL);
89 ALLEGRO_ERROR("al_show_native_file_dialog failed: %s\n", buf);
90 }
91 return false;
92 }
93
94 if (flags & OFN_ALLOWMULTISELECT) {
95 int i;
96 /* Count number of file names in buf. */
97 fd->fc_path_count = 0;
98 i = skip_nul_terminated_string(buf);
99 while (1) {
100 if (buf[i] == '\0') {
101 fd->fc_path_count++;
102 if (buf[i+1] == '\0')
103 break;
104 }
105 i++;
106 }
107 }
108 else {
109 fd->fc_path_count = 1;
110 }
111
112 if (fd->fc_path_count == 1) {
113 fd->fc_paths = al_malloc(sizeof(void *));
114 fd->fc_paths[0] = al_create_path(buf);
115 }
116 else {
117 int i, p;
118 /* If multiple files were selected, the first string in buf is the
119 * directory name, followed by each of the file names terminated by NUL.
120 */
121 fd->fc_paths = al_malloc(fd->fc_path_count * sizeof(void *));
122 i = skip_nul_terminated_string(buf);
123 for (p = 0; p < (int)fd->fc_path_count; p++) {
124 fd->fc_paths[p] = al_create_path_for_directory(buf);
125 al_set_path_filename(fd->fc_paths[p], buf+i);
126 i += skip_nul_terminated_string(buf+i);
127 }
128 }
129
130 return true;
131}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Trent Gamblin
Member #261
April 2000
![]() |
Cloning the string wasn't the problem I had in mind. When you go to save a file sometimes you want a default filename, for examples when you do Save As. How is this specified if not through fc_initial_path? EDIT: Ok I think you last patch looks good (upon further inspection EDIT2: Here's what I came up with. Your patch fails in some cases. For example if you set the initial path to C:\Users\trent then it assumes trent is a filename. I check if it exists, if it does I check if it's a directory, if it doesn't exist I assume it's a file. 1diff --git a/addons/native_dialog/win_dialog.c b/addons/native_dialog/win_dialog.c
2index 1f2ffb0..04bd873 100644
3--- a/addons/native_dialog/win_dialog.c
4+++ b/addons/native_dialog/win_dialog.c
5@@ -17,6 +17,8 @@
6
7 #include "allegro5/allegro_windows.h"
8
9+#include <string.h>
10+
11 /* We use RichEdit by default. */
12 #include <richedit.h>
13 #include <shlobj.h> // for folder selector
14@@ -142,8 +144,12 @@ bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
15 ALLEGRO_DISPLAY_WIN *win_display;
16 int flags = 0;
17 bool ret;
18- char buf[4096] = "";
19+ const int BUFSIZE = 4096;
20+ char buf[BUFSIZE];
21 ALLEGRO_USTR *filter_string = NULL;
22+ ALLEGRO_PATH* initial_dir_path = NULL;
23+
24+ buf[0] = 0;
25
26 win_display = (ALLEGRO_DISPLAY_WIN *)display;
27
28@@ -166,12 +172,34 @@ bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
29 ofn.lpstrFilter = "All Files\0*.*\0\0";
30 }
31
32+ /* Provide buffer for file chosen by dialog. */
33 ofn.lpstrFile = buf;
34 ofn.nMaxFile = sizeof(buf);
35
36+ /* Initialize file name buffer and starting directory */
37 if (fd->fc_initial_path) {
38- ofn.lpstrInitialDir =
39- al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
40+ bool is_dir;
41+ const char *path = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
42+
43+ if (al_filename_exists(path)) {
44+ ALLEGRO_FS_ENTRY *fs = al_create_fs_entry(path);
45+ is_dir = al_get_fs_entry_mode(fs) & ALLEGRO_FILEMODE_ISDIR;
46+ al_destroy_fs_entry(fs);
47+ }
48+ else
49+ is_dir = false;
50+
51+ if (is_dir)
52+ ofn.lpstrInitialDir = al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP);
53+ else {
54+ strncpy(buf, al_path_cstr(fd->fc_initial_path, ALLEGRO_NATIVE_PATH_SEP), BUFSIZE - 1);
55+ /* Clone the directory */
56+ initial_dir_path = al_clone_path(fd->fc_initial_path);
57+ if (initial_dir_path) {
58+ al_set_path_filename(initial_dir_path, NULL);
59+ ofn.lpstrInitialDir = al_path_cstr(initial_dir_path, ALLEGRO_NATIVE_PATH_SEP);
60+ }
61+ }
62 }
63
64 if (fd->title)
65@@ -195,6 +223,10 @@ bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display,
66 ret = GetOpenFileName(&ofn);
67 }
68
69+ if (initial_dir_path) {
70+ al_destroy_path(initial_dir_path);
71+ }
72+
73 al_ustr_free(filter_string);
74
75 if (!ret) {
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Trent Gamblin said: EDIT2: Here's what I came up with. Your patch fails in some cases. For example if you set the initial path to C:\Users\trent then it assumes trent is a filename. I check if it exists, if it does I check if it's a directory, if it doesn't exist I assume it's a file. Okay, yeah, your patch looks fine and it passes my simple test program. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Trent Gamblin
Member #261
April 2000
![]() |
Thanks for the patch, it's committed.
|
tobing
Member #5,213
November 2004
![]() |
This needs a small fix to compile on Windows: diff --git a/addons/native_dialog/win_dialog.c b/addons/native_dialog/win_dialog.c index 04bd873..a47b9a6 100644 --- a/addons/native_dialog/win_dialog.c +++ b/addons/native_dialog/win_dialog.c @@ -144,8 +144,8 @@ bool _al_show_native_file_dialog(ALLEGRO_DISPLAY *display, ALLEGRO_DISPLAY_WIN *win_display; int flags = 0; bool ret; - const int BUFSIZE = 4096; - char buf[BUFSIZE]; + char buf[4096]; + const int BUFSIZE = sizeof(buf); ALLEGRO_USTR *filter_string = NULL; ALLEGRO_PATH* initial_dir_path = NULL;
|
SiegeLord
Member #7,827
October 2006
![]() |
Applied, thanks (and thanks for using git am, makes hunting down people's emails easier "For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
tobing said: This needs a small fix to compile on Windows It works with MinGW 4.8.1. Are you using MSVC? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
tobing
Member #5,213
November 2004
![]() |
Yes, I'm using MSVC 2013 right now. |
|