diff options
| author | Eli Zaretskii | 2013-11-23 17:15:24 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-11-23 17:15:24 +0200 |
| commit | 2d716d7574e8c00d9ff96a74ce7ac2325864af79 (patch) | |
| tree | c1ad2a955df9199c6bf575f10be5b0786e5f5529 /src | |
| parent | 66124e6165642bc44a4742d5a878badd0a2c9353 (diff) | |
| download | emacs-2d716d7574e8c00d9ff96a74ce7ac2325864af79.tar.gz emacs-2d716d7574e8c00d9ff96a74ce7ac2325864af79.zip | |
File selection converted and tested.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 9 | ||||
| -rw-r--r-- | src/w32.h | 3 | ||||
| -rw-r--r-- | src/w32fns.c | 249 |
3 files changed, 192 insertions, 69 deletions
| @@ -691,9 +691,6 @@ get_security_info (HANDLE handle, | |||
| 691 | ppSecurityDescriptor)); | 691 | ppSecurityDescriptor)); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | static int filename_to_ansi (const char *, char *); | ||
| 695 | static int filename_to_utf16 (const char *, wchar_t *); | ||
| 696 | |||
| 697 | static BOOL WINAPI | 694 | static BOOL WINAPI |
| 698 | get_file_security (const char *lpFileName, | 695 | get_file_security (const char *lpFileName, |
| 699 | SECURITY_INFORMATION RequestedInformation, | 696 | SECURITY_INFORMATION RequestedInformation, |
| @@ -1356,7 +1353,7 @@ codepage_for_filenames (CPINFO *cp_info) | |||
| 1356 | return file_name_codepage; | 1353 | return file_name_codepage; |
| 1357 | } | 1354 | } |
| 1358 | 1355 | ||
| 1359 | static int | 1356 | int |
| 1360 | filename_to_utf16 (const char *fn_in, wchar_t *fn_out) | 1357 | filename_to_utf16 (const char *fn_in, wchar_t *fn_out) |
| 1361 | { | 1358 | { |
| 1362 | int result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1, | 1359 | int result = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, fn_in, -1, |
| @@ -1383,7 +1380,7 @@ filename_to_utf16 (const char *fn_in, wchar_t *fn_out) | |||
| 1383 | return 0; | 1380 | return 0; |
| 1384 | } | 1381 | } |
| 1385 | 1382 | ||
| 1386 | static int | 1383 | int |
| 1387 | filename_from_utf16 (const wchar_t *fn_in, char *fn_out) | 1384 | filename_from_utf16 (const wchar_t *fn_in, char *fn_out) |
| 1388 | { | 1385 | { |
| 1389 | int result = WideCharToMultiByte (CP_UTF8, 0, fn_in, -1, | 1386 | int result = WideCharToMultiByte (CP_UTF8, 0, fn_in, -1, |
| @@ -1410,7 +1407,7 @@ filename_from_utf16 (const wchar_t *fn_in, char *fn_out) | |||
| 1410 | return 0; | 1407 | return 0; |
| 1411 | } | 1408 | } |
| 1412 | 1409 | ||
| 1413 | static int | 1410 | int |
| 1414 | filename_to_ansi (const char *fn_in, char *fn_out) | 1411 | filename_to_ansi (const char *fn_in, char *fn_out) |
| 1415 | { | 1412 | { |
| 1416 | wchar_t fn_utf16[MAX_PATH]; | 1413 | wchar_t fn_utf16[MAX_PATH]; |
| @@ -181,6 +181,9 @@ extern void syms_of_ntterm (void); | |||
| 181 | extern void dostounix_filename (register char *); | 181 | extern void dostounix_filename (register char *); |
| 182 | extern void unixtodos_filename (register char *); | 182 | extern void unixtodos_filename (register char *); |
| 183 | extern int filename_from_ansi (const char *, char *); | 183 | extern int filename_from_ansi (const char *, char *); |
| 184 | extern int filename_to_ansi (const char *, char *); | ||
| 185 | extern int filename_from_utf16 (const wchar_t *, char *); | ||
| 186 | extern int filename_to_utf16 (const char *, wchar_t *); | ||
| 184 | 187 | ||
| 185 | extern BOOL init_winsock (int load_now); | 188 | extern BOOL init_winsock (int load_now); |
| 186 | extern void srandom (int); | 189 | extern void srandom (int); |
diff --git a/src/w32fns.c b/src/w32fns.c index eb77980af79..3e7ba910c22 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -6249,18 +6249,31 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 6249 | { | 6249 | { |
| 6250 | if (msg == WM_NOTIFY) | 6250 | if (msg == WM_NOTIFY) |
| 6251 | { | 6251 | { |
| 6252 | OFNOTIFYW * notify_w = (OFNOTIFYW *)lParam; | ||
| 6253 | OFNOTIFYA * notify_a = (OFNOTIFYA *)lParam; | ||
| 6254 | int dropdown_changed; | ||
| 6255 | int dir_index; | ||
| 6252 | #ifdef NTGUI_UNICODE | 6256 | #ifdef NTGUI_UNICODE |
| 6253 | OFNOTIFYW * notify = (OFNOTIFYW *)lParam; | 6257 | int use_unicode = 1; |
| 6254 | #else /* !NTGUI_UNICODE */ | 6258 | #else /* !NTGUI_UNICODE */ |
| 6255 | OFNOTIFYA * notify = (OFNOTIFYA *)lParam; | 6259 | int use_unicode = w32_unicode_filenames; |
| 6256 | #endif /* NTGUI_UNICODE */ | 6260 | #endif /* NTGUI_UNICODE */ |
| 6261 | |||
| 6257 | /* Detect when the Filter dropdown is changed. */ | 6262 | /* Detect when the Filter dropdown is changed. */ |
| 6258 | if (notify->hdr.code == CDN_TYPECHANGE | 6263 | if (use_unicode) |
| 6259 | || notify->hdr.code == CDN_INITDONE) | 6264 | dropdown_changed = |
| 6265 | notify_w->hdr.code == CDN_TYPECHANGE | ||
| 6266 | || notify_w->hdr.code == CDN_INITDONE; | ||
| 6267 | else | ||
| 6268 | dropdown_changed = | ||
| 6269 | notify_a->hdr.code == CDN_TYPECHANGE | ||
| 6270 | || notify_a->hdr.code == CDN_INITDONE; | ||
| 6271 | if (dropdown_changed) | ||
| 6260 | { | 6272 | { |
| 6261 | HWND dialog = GetParent (hwnd); | 6273 | HWND dialog = GetParent (hwnd); |
| 6262 | HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); | 6274 | HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); |
| 6263 | HWND list = GetDlgItem (dialog, FILE_NAME_LIST); | 6275 | HWND list = GetDlgItem (dialog, FILE_NAME_LIST); |
| 6276 | int hdr_code; | ||
| 6264 | 6277 | ||
| 6265 | /* At least on Windows 7, the above attempt to get the window handle | 6278 | /* At least on Windows 7, the above attempt to get the window handle |
| 6266 | to the File Name Text Field fails. The following code does the | 6279 | to the File Name Text Field fails. The following code does the |
| @@ -6278,10 +6291,24 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 6278 | } | 6291 | } |
| 6279 | 6292 | ||
| 6280 | /* Directories is in index 2. */ | 6293 | /* Directories is in index 2. */ |
| 6281 | if (notify->lpOFN->nFilterIndex == 2) | 6294 | if (use_unicode) |
| 6295 | { | ||
| 6296 | dir_index = notify_w->lpOFN->nFilterIndex; | ||
| 6297 | hdr_code = notify_w->hdr.code; | ||
| 6298 | } | ||
| 6299 | else | ||
| 6300 | { | ||
| 6301 | dir_index = notify_a->lpOFN->nFilterIndex; | ||
| 6302 | hdr_code = notify_a->hdr.code; | ||
| 6303 | } | ||
| 6304 | if (dir_index == 2) | ||
| 6282 | { | 6305 | { |
| 6283 | CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, | 6306 | if (use_unicode) |
| 6284 | GUISTR ("Current Directory")); | 6307 | SendMessageW (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD, |
| 6308 | (LPARAM)L"Current Directory"); | ||
| 6309 | else | ||
| 6310 | SendMessageA (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD, | ||
| 6311 | (LPARAM)"Current Directory"); | ||
| 6285 | EnableWindow (edit_control, FALSE); | 6312 | EnableWindow (edit_control, FALSE); |
| 6286 | /* Note that at least on Windows 7, the above call to EnableWindow | 6313 | /* Note that at least on Windows 7, the above call to EnableWindow |
| 6287 | disables the window that would ordinarily have focus. If we | 6314 | disables the window that would ordinarily have focus. If we |
| @@ -6289,16 +6316,21 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |||
| 6289 | no man's land and the user will be unable to tab through the | 6316 | no man's land and the user will be unable to tab through the |
| 6290 | dialog box (pressing tab will only result in a beep). | 6317 | dialog box (pressing tab will only result in a beep). |
| 6291 | Avoid that problem by setting focus to the list here. */ | 6318 | Avoid that problem by setting focus to the list here. */ |
| 6292 | if (notify->hdr.code == CDN_INITDONE) | 6319 | if (hdr_code == CDN_INITDONE) |
| 6293 | SetFocus (list); | 6320 | SetFocus (list); |
| 6294 | } | 6321 | } |
| 6295 | else | 6322 | else |
| 6296 | { | 6323 | { |
| 6297 | /* Don't override default filename on init done. */ | 6324 | /* Don't override default filename on init done. */ |
| 6298 | if (notify->hdr.code == CDN_TYPECHANGE) | 6325 | if (hdr_code == CDN_TYPECHANGE) |
| 6299 | CommDlg_OpenSave_SetControlText (dialog, | 6326 | { |
| 6300 | FILE_NAME_TEXT_FIELD, | 6327 | if (use_unicode) |
| 6301 | GUISTR ("")); | 6328 | SendMessageW (dialog, CDM_SETCONTROLTEXT, |
| 6329 | FILE_NAME_TEXT_FIELD, (LPARAM)L""); | ||
| 6330 | else | ||
| 6331 | SendMessageA (dialog, CDM_SETCONTROLTEXT, | ||
| 6332 | FILE_NAME_TEXT_FIELD, (LPARAM)""); | ||
| 6333 | } | ||
| 6302 | EnableWindow (edit_control, TRUE); | 6334 | EnableWindow (edit_control, TRUE); |
| 6303 | } | 6335 | } |
| 6304 | } | 6336 | } |
| @@ -6318,8 +6350,8 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6318 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) | 6350 | (Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p) |
| 6319 | { | 6351 | { |
| 6320 | /* Filter index: 1: All Files, 2: Directories only */ | 6352 | /* Filter index: 1: All Files, 2: Directories only */ |
| 6321 | static const guichar_t filter[] = | 6353 | static const wchar_t filter_w[] = L"All Files (*.*)\0*.*\0Directories\0*|*\0"; |
| 6322 | GUISTR ("All Files (*.*)\0*.*\0Directories\0*|*\0"); | 6354 | static const char filter_a[] = "All Files (*.*)\0*.*\0Directories\0*|*\0"; |
| 6323 | 6355 | ||
| 6324 | Lisp_Object filename = default_filename; | 6356 | Lisp_Object filename = default_filename; |
| 6325 | struct frame *f = SELECTED_FRAME (); | 6357 | struct frame *f = SELECTED_FRAME (); |
| @@ -6332,25 +6364,36 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6332 | enough struct for the new dialog to trick GetOpenFileName into | 6364 | enough struct for the new dialog to trick GetOpenFileName into |
| 6333 | giving us the new dialogs on newer versions of Windows. */ | 6365 | giving us the new dialogs on newer versions of Windows. */ |
| 6334 | struct { | 6366 | struct { |
| 6335 | #ifdef NTGUI_UNICODE | ||
| 6336 | OPENFILENAMEW details; | 6367 | OPENFILENAMEW details; |
| 6337 | #else /* !NTGUI_UNICODE */ | ||
| 6338 | OPENFILENAMEA details; | ||
| 6339 | #endif /* NTGUI_UNICODE */ | ||
| 6340 | |||
| 6341 | #if _WIN32_WINNT < 0x500 /* < win2k */ | 6368 | #if _WIN32_WINNT < 0x500 /* < win2k */ |
| 6342 | PVOID pvReserved; | 6369 | PVOID pvReserved; |
| 6343 | DWORD dwReserved; | 6370 | DWORD dwReserved; |
| 6344 | DWORD FlagsEx; | 6371 | DWORD FlagsEx; |
| 6345 | #endif /* < win2k */ | 6372 | #endif /* < win2k */ |
| 6346 | } new_file_details; | 6373 | } new_file_details_w; |
| 6347 | 6374 | ||
| 6348 | #ifdef NTGUI_UNICODE | 6375 | #ifdef NTGUI_UNICODE |
| 6349 | wchar_t filename_buf[32*1024 + 1]; // NT kernel maximum | 6376 | wchar_t filename_buf_w[32*1024 + 1]; // NT kernel maximum |
| 6350 | OPENFILENAMEW * file_details = &new_file_details.details; | 6377 | OPENFILENAMEW * file_details_w = &new_file_details_w.details; |
| 6378 | int use_unicode = 1; | ||
| 6351 | #else /* not NTGUI_UNICODE */ | 6379 | #else /* not NTGUI_UNICODE */ |
| 6352 | char filename_buf[MAX_PATH + 1]; | 6380 | struct { |
| 6353 | OPENFILENAMEA * file_details = &new_file_details.details; | 6381 | OPENFILENAMEA details; |
| 6382 | #if _WIN32_WINNT < 0x500 /* < win2k */ | ||
| 6383 | PVOID pvReserved; | ||
| 6384 | DWORD dwReserved; | ||
| 6385 | DWORD FlagsEx; | ||
| 6386 | #endif /* < win2k */ | ||
| 6387 | } new_file_details_a; | ||
| 6388 | wchar_t filename_buf_w[MAX_PATH + 1], dir_w[MAX_PATH]; | ||
| 6389 | char filename_buf_a[MAX_PATH + 1], dir_a[MAX_PATH]; | ||
| 6390 | OPENFILENAMEW * file_details_w = &new_file_details_w.details; | ||
| 6391 | OPENFILENAMEA * file_details_a = &new_file_details_a.details; | ||
| 6392 | int use_unicode = w32_unicode_filenames; | ||
| 6393 | wchar_t *prompt_w; | ||
| 6394 | char *prompt_a; | ||
| 6395 | int len; | ||
| 6396 | char fname_ret[MAX_UTF8_PATH]; | ||
| 6354 | #endif /* NTGUI_UNICODE */ | 6397 | #endif /* NTGUI_UNICODE */ |
| 6355 | 6398 | ||
| 6356 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | 6399 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; |
| @@ -6396,6 +6439,10 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6396 | to_unicode (prompt, &prompt); | 6439 | to_unicode (prompt, &prompt); |
| 6397 | to_unicode (dir, &dir); | 6440 | to_unicode (dir, &dir); |
| 6398 | to_unicode (filename, &filename); | 6441 | to_unicode (filename, &filename); |
| 6442 | if (SBYTES (filename) + 1 > sizeof (filename_buf_w)) | ||
| 6443 | report_file_error ("filename too long", default_filename); | ||
| 6444 | |||
| 6445 | memcpy (filename_buf_w, SDATA (filename), SBYTES (filename) + 1); | ||
| 6399 | #else /* !NTGUI_UNICODE */ | 6446 | #else /* !NTGUI_UNICODE */ |
| 6400 | prompt = ENCODE_FILE (prompt); | 6447 | prompt = ENCODE_FILE (prompt); |
| 6401 | dir = ENCODE_FILE (dir); | 6448 | dir = ENCODE_FILE (dir); |
| @@ -6406,6 +6453,43 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6406 | unixtodos_filename (SDATA (dir)); | 6453 | unixtodos_filename (SDATA (dir)); |
| 6407 | filename = Fcopy_sequence (filename); | 6454 | filename = Fcopy_sequence (filename); |
| 6408 | unixtodos_filename (SDATA (filename)); | 6455 | unixtodos_filename (SDATA (filename)); |
| 6456 | if (SBYTES (filename) >= MAX_UTF8_PATH) | ||
| 6457 | report_file_error ("filename too long", default_filename); | ||
| 6458 | if (w32_unicode_filenames) | ||
| 6459 | { | ||
| 6460 | filename_to_utf16 (SSDATA (dir), dir_w); | ||
| 6461 | if (filename_to_utf16 (SSDATA (filename), filename_buf_w) != 0) | ||
| 6462 | { | ||
| 6463 | /* filename_to_utf16 sets errno to ENOENT when the file | ||
| 6464 | name is too long or cannot be converted to UTF-16. */ | ||
| 6465 | if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0) | ||
| 6466 | report_file_error ("filename too long", default_filename); | ||
| 6467 | } | ||
| 6468 | len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 6469 | SSDATA (prompt), -1, NULL, 0); | ||
| 6470 | prompt_w = alloca (len * sizeof (wchar_t)); | ||
| 6471 | MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 6472 | SSDATA (prompt), -1, prompt_w, len); | ||
| 6473 | } | ||
| 6474 | else | ||
| 6475 | { | ||
| 6476 | filename_to_ansi (SSDATA (dir), dir_a); | ||
| 6477 | if (filename_to_ansi (SSDATA (filename), filename_buf_a) != '\0') | ||
| 6478 | { | ||
| 6479 | /* filename_to_ansi sets errno to ENOENT when the file | ||
| 6480 | name is too long or cannot be converted to UTF-16. */ | ||
| 6481 | if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0) | ||
| 6482 | report_file_error ("filename too long", default_filename); | ||
| 6483 | } | ||
| 6484 | len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 6485 | SSDATA (prompt), -1, NULL, 0); | ||
| 6486 | prompt_w = alloca (len * sizeof (wchar_t)); | ||
| 6487 | MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, | ||
| 6488 | SSDATA (prompt), -1, prompt_w, len); | ||
| 6489 | len = WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL); | ||
| 6490 | prompt_a = alloca (len); | ||
| 6491 | WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL); | ||
| 6492 | } | ||
| 6409 | #endif /* NTGUI_UNICODE */ | 6493 | #endif /* NTGUI_UNICODE */ |
| 6410 | 6494 | ||
| 6411 | /* Fill in the structure for the call to GetOpenFileName below. | 6495 | /* Fill in the structure for the call to GetOpenFileName below. |
| @@ -6414,38 +6498,65 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6414 | builds, we tell the OS we're using an old version of the | 6498 | builds, we tell the OS we're using an old version of the |
| 6415 | structure if the OS isn't new enough to support the newer | 6499 | structure if the OS isn't new enough to support the newer |
| 6416 | version. */ | 6500 | version. */ |
| 6417 | memset (&new_file_details, 0, sizeof (new_file_details)); | 6501 | if (use_unicode) |
| 6418 | 6502 | { | |
| 6419 | if (w32_major_version > 4 && w32_major_version < 95) | 6503 | memset (&new_file_details_w, 0, sizeof (new_file_details_w)); |
| 6420 | file_details->lStructSize = sizeof (new_file_details); | 6504 | if (w32_major_version > 4 && w32_major_version < 95) |
| 6505 | file_details_w->lStructSize = sizeof (new_file_details_w); | ||
| 6506 | else | ||
| 6507 | file_details_w->lStructSize = sizeof (*file_details_w); | ||
| 6508 | /* Set up the inout parameter for the selected file name. */ | ||
| 6509 | file_details_w->lpstrFile = filename_buf_w; | ||
| 6510 | file_details_w->nMaxFile = | ||
| 6511 | sizeof (filename_buf_w) / sizeof (*filename_buf_w); | ||
| 6512 | file_details_w->hwndOwner = FRAME_W32_WINDOW (f); | ||
| 6513 | /* Undocumented Bug in Common File Dialog: | ||
| 6514 | If a filter is not specified, shell links are not resolved. */ | ||
| 6515 | file_details_w->lpstrFilter = filter_w; | ||
| 6516 | #ifdef NTGUI_UNICODE | ||
| 6517 | file_details_w->lpstrInitialDir = (wchar_t*) SDATA (dir); | ||
| 6518 | file_details->lpstrTitle = (guichar_t*) SDATA (prompt); | ||
| 6519 | #else | ||
| 6520 | file_details_w->lpstrInitialDir = dir_w; | ||
| 6521 | file_details_w->lpstrTitle = prompt_w; | ||
| 6522 | #endif | ||
| 6523 | file_details_w->nFilterIndex = NILP (only_dir_p) ? 1 : 2; | ||
| 6524 | file_details_w->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR | ||
| 6525 | | OFN_EXPLORER | OFN_ENABLEHOOK); | ||
| 6526 | if (!NILP (mustmatch)) | ||
| 6527 | { | ||
| 6528 | /* Require that the path to the parent directory exists. */ | ||
| 6529 | file_details_w->Flags |= OFN_PATHMUSTEXIST; | ||
| 6530 | /* If we are looking for a file, require that it exists. */ | ||
| 6531 | if (NILP (only_dir_p)) | ||
| 6532 | file_details_w->Flags |= OFN_FILEMUSTEXIST; | ||
| 6533 | } | ||
| 6534 | } | ||
| 6421 | else | 6535 | else |
| 6422 | file_details->lStructSize = sizeof (*file_details); | ||
| 6423 | |||
| 6424 | /* Set up the inout parameter for the selected file name. */ | ||
| 6425 | if (SBYTES (filename) + 1 > sizeof (filename_buf)) | ||
| 6426 | report_file_error ("filename too long", default_filename); | ||
| 6427 | |||
| 6428 | memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1); | ||
| 6429 | file_details->lpstrFile = filename_buf; | ||
| 6430 | file_details->nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf); | ||
| 6431 | |||
| 6432 | file_details->hwndOwner = FRAME_W32_WINDOW (f); | ||
| 6433 | /* Undocumented Bug in Common File Dialog: | ||
| 6434 | If a filter is not specified, shell links are not resolved. */ | ||
| 6435 | file_details->lpstrFilter = filter; | ||
| 6436 | file_details->lpstrInitialDir = (guichar_t*) SDATA (dir); | ||
| 6437 | file_details->lpstrTitle = (guichar_t*) SDATA (prompt); | ||
| 6438 | file_details->nFilterIndex = NILP (only_dir_p) ? 1 : 2; | ||
| 6439 | file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR | ||
| 6440 | | OFN_EXPLORER | OFN_ENABLEHOOK); | ||
| 6441 | |||
| 6442 | if (!NILP (mustmatch)) | ||
| 6443 | { | 6536 | { |
| 6444 | /* Require that the path to the parent directory exists. */ | 6537 | memset (&new_file_details_a, 0, sizeof (new_file_details_a)); |
| 6445 | file_details->Flags |= OFN_PATHMUSTEXIST; | 6538 | if (w32_major_version > 4 && w32_major_version < 95) |
| 6446 | /* If we are looking for a file, require that it exists. */ | 6539 | file_details_a->lStructSize = sizeof (new_file_details_a); |
| 6447 | if (NILP (only_dir_p)) | 6540 | else |
| 6448 | file_details->Flags |= OFN_FILEMUSTEXIST; | 6541 | file_details_a->lStructSize = sizeof (*file_details_a); |
| 6542 | file_details_a->lpstrFile = filename_buf_a; | ||
| 6543 | file_details_a->nMaxFile = | ||
| 6544 | sizeof (filename_buf_a) / sizeof (*filename_buf_a); | ||
| 6545 | file_details_a->hwndOwner = FRAME_W32_WINDOW (f); | ||
| 6546 | file_details_a->lpstrFilter = filter_a; | ||
| 6547 | file_details_a->lpstrInitialDir = dir_a; | ||
| 6548 | file_details_a->lpstrTitle = prompt_a; | ||
| 6549 | file_details_a->nFilterIndex = NILP (only_dir_p) ? 1 : 2; | ||
| 6550 | file_details_a->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR | ||
| 6551 | | OFN_EXPLORER | OFN_ENABLEHOOK); | ||
| 6552 | if (!NILP (mustmatch)) | ||
| 6553 | { | ||
| 6554 | /* Require that the path to the parent directory exists. */ | ||
| 6555 | file_details_a->Flags |= OFN_PATHMUSTEXIST; | ||
| 6556 | /* If we are looking for a file, require that it exists. */ | ||
| 6557 | if (NILP (only_dir_p)) | ||
| 6558 | file_details_a->Flags |= OFN_FILEMUSTEXIST; | ||
| 6559 | } | ||
| 6449 | } | 6560 | } |
| 6450 | 6561 | ||
| 6451 | { | 6562 | { |
| @@ -6453,9 +6564,18 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6453 | /* Prevent redisplay. */ | 6564 | /* Prevent redisplay. */ |
| 6454 | specbind (Qinhibit_redisplay, Qt); | 6565 | specbind (Qinhibit_redisplay, Qt); |
| 6455 | block_input (); | 6566 | block_input (); |
| 6456 | file_details->lpfnHook = file_dialog_callback; | 6567 | if (use_unicode) |
| 6568 | { | ||
| 6569 | file_details_w->lpfnHook = file_dialog_callback; | ||
| 6570 | |||
| 6571 | file_opened = GetOpenFileNameW (file_details_w); | ||
| 6572 | } | ||
| 6573 | else | ||
| 6574 | { | ||
| 6575 | file_details_a->lpfnHook = file_dialog_callback; | ||
| 6457 | 6576 | ||
| 6458 | file_opened = GUI_FN (GetOpenFileName) (file_details); | 6577 | file_opened = GetOpenFileNameA (file_details_a); |
| 6578 | } | ||
| 6459 | unblock_input (); | 6579 | unblock_input (); |
| 6460 | unbind_to (count, Qnil); | 6580 | unbind_to (count, Qnil); |
| 6461 | } | 6581 | } |
| @@ -6464,10 +6584,14 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6464 | { | 6584 | { |
| 6465 | /* Get an Emacs string from the value Windows gave us. */ | 6585 | /* Get an Emacs string from the value Windows gave us. */ |
| 6466 | #ifdef NTGUI_UNICODE | 6586 | #ifdef NTGUI_UNICODE |
| 6467 | filename = from_unicode_buffer (filename_buf); | 6587 | filename = from_unicode_buffer (filename_buf_w); |
| 6468 | #else /* !NTGUI_UNICODE */ | 6588 | #else /* !NTGUI_UNICODE */ |
| 6469 | filename = DECODE_FILE (build_unibyte_string (filename_buf)); | 6589 | if (use_unicode) |
| 6470 | dostounix_filename (SSDATA (filename)); | 6590 | filename_from_utf16 (filename_buf_w, fname_ret); |
| 6591 | else | ||
| 6592 | filename_from_ansi (filename_buf_a, fname_ret); | ||
| 6593 | dostounix_filename (fname_ret); | ||
| 6594 | filename = DECODE_FILE (build_unibyte_string (fname_ret)); | ||
| 6471 | #endif /* NTGUI_UNICODE */ | 6595 | #endif /* NTGUI_UNICODE */ |
| 6472 | 6596 | ||
| 6473 | #ifdef CYGWIN | 6597 | #ifdef CYGWIN |
| @@ -6476,10 +6600,9 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6476 | 6600 | ||
| 6477 | /* Strip the dummy filename off the end of the string if we | 6601 | /* Strip the dummy filename off the end of the string if we |
| 6478 | added it to select a directory. */ | 6602 | added it to select a directory. */ |
| 6479 | if (file_details->nFilterIndex == 2) | 6603 | if (use_unicode && file_details_w->nFilterIndex == 2 |
| 6480 | { | 6604 | || !use_unicode && file_details_a->nFilterIndex == 2) |
| 6481 | filename = Ffile_name_directory (filename); | 6605 | filename = Ffile_name_directory (filename); |
| 6482 | } | ||
| 6483 | } | 6606 | } |
| 6484 | /* User canceled the dialog without making a selection. */ | 6607 | /* User canceled the dialog without making a selection. */ |
| 6485 | else if (!CommDlgExtendedError ()) | 6608 | else if (!CommDlgExtendedError ()) |