Mercurial > hg > xemacs-beta
diff src/dialog-msw.c @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | a307f9a2021d |
children | e38acbeb1cae |
line wrap: on
line diff
--- a/src/dialog-msw.c Fri Mar 08 13:33:14 2002 +0000 +++ b/src/dialog-msw.c Wed Mar 13 08:54:06 2002 +0000 @@ -1,6 +1,6 @@ /* Implements elisp-programmable dialog boxes -- MS Windows interface. Copyright (C) 1998 Kirill M. Katsnelson <kkm@kis.ru> - Copyright (C) 2000 Ben Wing. + Copyright (C) 2000, 2001, 2002 Ben Wing. This file is part of XEmacs. @@ -21,6 +21,9 @@ /* Synched up with: Not in FSF. */ +/* This file essentially Mule-ized (except perhaps some Unicode splitting). + 5-2000. */ + /* Author: Initially written by kkm, May 1998 */ @@ -34,8 +37,7 @@ #include "gui.h" #include "opaque.h" -#include <cderr.h> -#include <commdlg.h> +#include "sysfile.h" Lisp_Object Qdialog_box_error; @@ -148,7 +150,7 @@ { LIST_LOOP_2 (data, Vdialog_data_list) { - if (IsDialogMessage (XMSWINDOWS_DIALOG_ID (data)->hwnd, msg)) + if (qxeIsDialogMessage (XMSWINDOWS_DIALOG_ID (data)->hwnd, msg)) return 1; } @@ -159,7 +161,7 @@ /* This is a windows feature that allows dialog type processing to be applied to standard windows containing controls. */ - if (IsDialogMessage (hwnd, msg)) + if (qxeIsDialogMessage (hwnd, msg)) return 1; } } @@ -186,13 +188,13 @@ switch (msg) { case WM_INITDIALOG: - SetWindowLong (hwnd, DWL_USER, l_param); + qxeSetWindowLong (hwnd, DWL_USER, l_param); break; case WM_DESTROY: { Lisp_Object data; - VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER)); + VOID_TO_LISP (data, qxeGetWindowLong (hwnd, DWL_USER)); Vdialog_data_list = delq_no_quit (data, Vdialog_data_list); } break; @@ -202,7 +204,7 @@ Lisp_Object fn, arg, data; struct mswindows_dialog_id *did; - VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER)); + VOID_TO_LISP (data, qxeGetWindowLong (hwnd, DWL_USER)); did = XMSWINDOWS_DIALOG_ID (data); if (w_param != IDCANCEL) /* user pressed escape */ { @@ -219,7 +221,7 @@ mswindows_enqueue_misc_user_event (did->frame, Qrun_hooks, Qmenu_no_selection_hook); /* #### need to error-protect! will do so when i merge in - my working ws */ + my stderr-proc ws */ va_run_hook_with_args (Qdelete_dialog_box_hook, 1, data); DestroyWindow (hwnd); @@ -235,45 +237,28 @@ /* Helper function which converts the supplied string STRING into Unicode and pushes it at the end of DYNARR */ static void -push_lisp_string_as_unicode (unsigned_char_dynarr* dynarr, Lisp_Object string) +push_lisp_string_as_unicode (unsigned_char_dynarr *dynarr, Lisp_Object string) { - Extbyte *mbcs_string; - Charcount length = XSTRING_CHAR_LENGTH (string); - LPWSTR uni_string; + int length; + Extbyte *uni_string; TO_EXTERNAL_FORMAT (LISP_STRING, string, - C_STRING_ALLOCA, mbcs_string, - Qnative); - uni_string = alloca_array (WCHAR, length + 1); - length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1, - uni_string, sizeof(WCHAR) * (length + 1)); - Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length); -} - -/* Helper function which converts the supplied string STRING into Unicode and - pushes it at the end of DYNARR */ -static void -push_intbyte_string_as_unicode (unsigned_char_dynarr* dynarr, Intbyte *string, - Bytecount len) -{ - Extbyte *mbcs_string; - Charcount length = bytecount_to_charcount (string, len); - LPWSTR uni_string; - - TO_EXTERNAL_FORMAT (C_STRING, string, - C_STRING_ALLOCA, mbcs_string, - Qnative); - uni_string = alloca_array (WCHAR, length + 1); - length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1, - uni_string, sizeof(WCHAR) * (length + 1)); - Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length); + ALLOCA, (uni_string, length), + Qmswindows_unicode); + Dynarr_add_many (dynarr, uni_string, length); + Dynarr_add (dynarr, '\0'); + Dynarr_add (dynarr, '\0'); } /* Given button TEXT, return button width in DLU */ static int button_width (Lisp_Object text) { - int width = X_DLU_PER_CHAR * XSTRING_CHAR_LENGTH (text); + /* !!#### do Japanese chars count as two? */ + int width = + X_DLU_PER_CHAR * + intbyte_string_displayed_columns (XSTRING_DATA (text), + XSTRING_LENGTH (text)); return max (X_MIN_BUTTON, width); } @@ -290,6 +275,7 @@ dialog_popped_down (Lisp_Object arg) { popup_up_p--; + return Qnil; } @@ -303,7 +289,7 @@ static struct { DWORD errmess; - char *errname; + Char_ASCII *errname; } common_dialog_errors[] = { { CDERR_DIALOGFAILURE, "CDERR_DIALOGFAILURE" }, @@ -339,9 +325,10 @@ { FRERR_BUFFERLENGTHZERO, "FRERR_BUFFERLENGTHZERO" }, }; -struct param_data { - char* fname; - char* unknown_fname; +struct param_data +{ + Extbyte *fname; + Extbyte *unknown_fname; int validate; }; @@ -349,33 +336,33 @@ CALLBACK handle_directory_proc (HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData) { - TCHAR szDir[MAX_PATH]; - struct param_data* pd = (struct param_data*)lpData; + Extbyte szDir[MAX_PATH * MAX_XETCHAR_SIZE]; + struct param_data *pd = (struct param_data *) lpData; - switch(msg) { - case BFFM_INITIALIZED: - // WParam is TRUE since you are passing a path. - // It would be FALSE if you were passing a pidl. - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)pd->fname); - break; - - case BFFM_SELCHANGED: - // Set the status window to the currently selected path. - if (SHGetPathFromIDList((LPITEMIDLIST) lParam, szDir)) { - SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)szDir); + switch (msg) + { + case BFFM_INITIALIZED: + /* WParam is TRUE since you are passing a path. + It would be FALSE if you were passing a pidl. */ + qxeSendMessage (hwnd, BFFM_SETSELECTION, TRUE, (LPARAM) pd->fname); + break; + + case BFFM_SELCHANGED: + /* Set the status window to the currently selected path. */ + if (qxeSHGetPathFromIDList ((LPITEMIDLIST) lParam, szDir)) + qxeSendMessage (hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) szDir); + break; + + case BFFM_VALIDATEFAILED: + if (pd->validate) + return TRUE; + else + pd->unknown_fname = xetcsdup ((Extbyte *) lParam); + break; + + default: + break; } - break; - - case BFFM_VALIDATEFAILED: - if (pd->validate) - return TRUE; - else - pd->unknown_fname = xstrdup((char*)lParam); - break; - - default: - break; - } return 0; } @@ -383,24 +370,25 @@ handle_directory_dialog_box (struct frame *f, Lisp_Object keys) { Lisp_Object ret = Qnil; - BROWSEINFO bi; + BROWSEINFOW bi; LPITEMIDLIST pidl; LPMALLOC pMalloc; struct param_data pd; - - xzero(pd); - xzero(bi); - - bi.lParam = (LPARAM)&pd; + + xzero (pd); + xzero (bi); + + bi.lParam = (LPARAM) &pd; bi.hwndOwner = FRAME_MSWINDOWS_HANDLE (f); bi.pszDisplayName = 0; bi.pidlRoot = 0; - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_EDITBOX; + bi.ulFlags = + BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_EDITBOX | BIF_NEWDIALOGSTYLE; bi.lpfn = handle_directory_proc; - + LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (build_string (""), Qnil), - (char*)pd.fname); - + pd.fname); + { EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) { @@ -416,10 +404,11 @@ ; /* do nothing */ else if (EQ (key, Q_file_must_exist)) { - if (!NILP (value)) { - pd.validate = TRUE; - bi.ulFlags |= BIF_VALIDATE; - } + if (!NILP (value)) + { + pd.validate = TRUE; + bi.ulFlags |= BIF_VALIDATE; + } else bi.ulFlags &= ~BIF_VALIDATE; } @@ -427,25 +416,26 @@ invalid_constant ("Unrecognized directory-dialog keyword", key); } } - - if (SHGetMalloc(&pMalloc) == NOERROR) + + if (SHGetMalloc (&pMalloc) == NOERROR) { - pidl = SHBrowseForFolder(&bi); - if (pidl) { - TCHAR* szDir = alloca (MAX_PATH); - - if (SHGetPathFromIDList(pidl, szDir)) { - ret = tstr_to_local_file_format (szDir); + pidl = qxeSHBrowseForFolder (&bi); + if (pidl) + { + Extbyte *szDir = alloca_extbytes (MAX_PATH * MAX_XETCHAR_SIZE); + + if (qxeSHGetPathFromIDList (pidl, szDir)) + ret = tstr_to_local_file_format (szDir); + + XECOMCALL1 (pMalloc, Free, pidl); + XECOMCALL0 (pMalloc, Release); + return ret; } - - pMalloc->lpVtbl->Free(pMalloc, pidl); - pMalloc->lpVtbl->Release(pMalloc); - return ret; - } - else if (pd.unknown_fname != 0) { - ret = tstr_to_local_file_format (pd.unknown_fname); - xfree(pd.unknown_fname); - } + else if (pd.unknown_fname != 0) + { + ret = tstr_to_local_file_format (pd.unknown_fname); + xfree (pd.unknown_fname); + } else while (1) signal_quit (); } @@ -459,28 +449,27 @@ static Lisp_Object handle_file_dialog_box (struct frame *f, Lisp_Object keys) { - OPENFILENAME ofn; + OPENFILENAMEW ofn; + Extbyte fnbuf[8000]; - char fnbuf[8000]; - xzero (ofn); ofn.lStructSize = sizeof (ofn); ofn.Flags = OFN_EXPLORER; ofn.hwndOwner = FRAME_MSWINDOWS_HANDLE (f); - ofn.lpstrFile = fnbuf; + ofn.lpstrFile = (XELPTSTR) fnbuf; ofn.nMaxFile = sizeof (fnbuf) / XETCHAR_SIZE; xetcscpy (fnbuf, XETEXT ("")); - + LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (build_string (""), Qnil), ofn.lpstrInitialDir); - + { EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) { if (EQ (key, Q_initial_filename)) { Extbyte *fnout; - + CHECK_STRING (value); LOCAL_FILE_FORMAT_TO_TSTR (value, fnout); xetcscpy (fnbuf, fnout); @@ -488,7 +477,7 @@ else if (EQ (key, Q_title)) { CHECK_STRING (value); - LISP_STRING_TO_EXTERNAL (value, ofn.lpstrTitle, Qmswindows_tstr); + LISP_STRING_TO_TSTR (value, ofn.lpstrTitle); } else if (EQ (key, Q_initial_directory)) LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (value, Qnil), @@ -504,8 +493,8 @@ invalid_constant ("Unrecognized file-dialog keyword", key); } } - - if (!GetOpenFileName (&ofn)) + + if (!qxeGetOpenFileName (&ofn)) { DWORD err = CommDlgExtendedError (); if (!err) @@ -516,23 +505,23 @@ else { int i; - + for (i = 0; i < countof (common_dialog_errors); i++) { if (common_dialog_errors[i].errmess == err) signal_error (Qdialog_box_error, "Creating file-dialog-box", - build_string + build_msg_string (common_dialog_errors[i].errname)); } - + signal_error (Qdialog_box_error, "Unknown common dialog box error???", make_int (err)); } } - - return tstr_to_local_file_format (ofn.lpstrFile); + + return tstr_to_local_file_format ((Extbyte *) ofn.lpstrFile); } static Lisp_Object @@ -543,16 +532,16 @@ int button_row_width = 0; int text_width, text_height; Lisp_Object question = Qnil, title = Qnil; - + int unbind_count = specpdl_depth (); record_unwind_protect (free_dynarr_opaque_ptr, make_opaque_ptr (dialog_items)); record_unwind_protect (free_dynarr_opaque_ptr, make_opaque_ptr (template_)); - + /* A big NO NEED to GCPRO gui_items stored in the array: they are just pointers into KEYS list, which is GC-protected by the caller */ - + { EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys) { @@ -569,7 +558,7 @@ else if (EQ (key, Q_buttons)) { Lisp_Object item_cons; - + /* Parse each item in the dialog into gui_item structs, and stuff a dynarr of these. Calculate button row width in this loop too */ @@ -584,20 +573,20 @@ + X_BUTTON_MARGIN; } } - + button_row_width -= X_BUTTON_MARGIN; } else invalid_constant ("Unrecognized question-dialog keyword", key); } } - + if (Dynarr_length (dialog_items) == 0) sferror ("Dialog descriptor provides no buttons", keys); - + if (NILP (question)) sferror ("Dialog descriptor provides no question", keys); - + /* Determine the final width layout */ { Intbyte *p = XSTRING_DATA (question); @@ -614,11 +603,11 @@ } else ++this_length; - + if (ch == (Emchar)'\0') break; } - + if (string_max * X_DLU_PER_CHAR > max (X_MAX_TEXT, button_row_width)) text_width = X_AVE_TEXT; else if (string_max * X_DLU_PER_CHAR < X_MIN_TEXT) @@ -648,7 +637,7 @@ } text_height = Y_TEXT_MARGIN + Y_DLU_PER_CHAR * num_lines; } - + /* Ok, now we are ready to stuff the dialog template and lay out controls */ { DLGTEMPLATE dlg_tem; @@ -658,9 +647,9 @@ const unsigned int ones = 0xFFFFFFFF; const WORD static_class_id = 0x0082; const WORD button_class_id = 0x0080; - + /* Create and stuff in DLGTEMPLATE header */ - dlg_tem.style = (DS_CENTER | DS_MODALFRAME | DS_SETFONT + dlg_tem.style = (DS_CENTER | DS_MODALFRAME | WS_CAPTION | WS_POPUP | WS_VISIBLE); dlg_tem.dwExtendedStyle = 0; dlg_tem.cdit = Dynarr_length (dialog_items) + 1; @@ -670,20 +659,17 @@ dlg_tem.cy = (Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON + Y_BUTTON + Y_BUTTON_FROM_EDGE); Dynarr_add_many (template_, &dlg_tem, sizeof (dlg_tem)); - + /* We want no menu and standard class */ Dynarr_add_many (template_, &zeroes, 4); - + /* And the third is the dialog title. "XEmacs" unless one is supplied. Note that the string must be in Unicode. */ if (NILP (title)) Dynarr_add_many (template_, L"XEmacs", 14); else push_lisp_string_as_unicode (template_, title); - - /* We want standard dialog font */ - Dynarr_add_many (template_, L"\x08MS Shell Dlg", 28); - + /* Next add text control. */ item_tem.style = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX; item_tem.dwExtendedStyle = 0; @@ -692,20 +678,20 @@ item_tem.cx = text_width; item_tem.cy = text_height; item_tem.id = 0xFFFF; - + ALIGN_TEMPLATE; Dynarr_add_many (template_, &item_tem, sizeof (item_tem)); - + /* Right after class id follows */ Dynarr_add_many (template_, &ones, 2); Dynarr_add_many (template_, &static_class_id, sizeof (static_class_id)); - + /* Next thing to add is control text, as Unicode string */ push_lisp_string_as_unicode (template_, question); - + /* Specify 0 length creation data */ Dynarr_add_many (template_, &zeroes, 2); - + /* Now it's the button time */ item_tem.y = Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON; item_tem.x = X_BUTTON_FROM_EDGE + (button_row_width < text_width @@ -713,51 +699,44 @@ : 0); item_tem.cy = Y_BUTTON; item_tem.dwExtendedStyle = 0; - + for (i = 0; i < Dynarr_length (dialog_items); ++i) { - Lisp_Object* gui_item = Dynarr_atp (dialog_items, i); + Lisp_Object *gui_item = Dynarr_atp (dialog_items, i); Lisp_Gui_Item *pgui_item = XGUI_ITEM (*gui_item); - + item_tem.style = (WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | (gui_item_active_p (*gui_item) ? 0 : WS_DISABLED)); item_tem.cx = button_width (pgui_item->name); /* Item ids are indices into dialog_items plus offset, to avoid having items by reserved ids (IDOK, IDCANCEL) */ item_tem.id = i + ID_ITEM_BIAS; - + ALIGN_TEMPLATE; Dynarr_add_many (template_, &item_tem, sizeof (item_tem)); - + /* Right after 0xFFFF and class id atom follows */ Dynarr_add_many (template_, &ones, 2); Dynarr_add_many (template_, &button_class_id, sizeof (button_class_id)); - + /* Next thing to add is control text, as Unicode string */ { - Lisp_Object ctext = pgui_item->name; Emchar accel_unused; - Intbyte *trans = (Intbyte *) alloca (2 * XSTRING_LENGTH (ctext) + 3); - Bytecount translen; - - memcpy (trans, XSTRING_DATA (ctext), XSTRING_LENGTH (ctext) + 1); - translen = - mswindows_translate_menu_or_dialog_item (trans, - XSTRING_LENGTH (ctext), - 2 * XSTRING_LENGTH (ctext) + 3, - &accel_unused, - ctext); - push_intbyte_string_as_unicode (template_, trans, translen); + + push_lisp_string_as_unicode + (template_, + mswindows_translate_menu_or_dialog_item + (pgui_item->name, &accel_unused)); } - + /* Specify 0 length creation data. */ Dynarr_add_many (template_, &zeroes, 2); - + item_tem.x += item_tem.cx + X_BUTTON_SPACING; } } - + /* Now the Windows dialog structure is ready. We need to prepare a data structure for the new dialog, which will contain callbacks and the frame for these callbacks. This structure has to be @@ -769,9 +748,9 @@ struct mswindows_dialog_id *did = alloc_lcrecord_type (struct mswindows_dialog_id, &lrecord_mswindows_dialog_id); - + XSETMSWINDOWS_DIALOG_ID (dialog_data, did); - + did->frame = wrap_frame (f); did->callbacks = make_vector (Dynarr_length (dialog_items), Qunbound); for (i = 0; i < Dynarr_length (dialog_items); i++) @@ -780,18 +759,18 @@ /* Woof! Everything is ready. Pop pop pop in now! */ did->hwnd = - CreateDialogIndirectParam (NULL, - (LPDLGTEMPLATE) Dynarr_atp (template_, 0), - FRAME_MSWINDOWS_HANDLE (f), dialog_proc, - (LPARAM) LISP_TO_VOID (dialog_data)); + qxeCreateDialogIndirectParam (NULL, + (LPDLGTEMPLATE) Dynarr_atp (template_, 0), + FRAME_MSWINDOWS_HANDLE (f), dialog_proc, + (LPARAM) LISP_TO_VOID (dialog_data)); if (!did->hwnd) /* Something went wrong creating the dialog */ signal_error (Qdialog_box_error, "Creating dialog", keys); - + Vdialog_data_list = Fcons (dialog_data, Vdialog_data_list); - + /* Cease protection and free dynarrays */ - unbind_to (unbind_count, Qnil); + unbind_to (unbind_count); return dialog_data; } } @@ -803,18 +782,19 @@ int unbind_count = specpdl_depth (); record_unwind_protect (dialog_popped_down, Qnil); popup_up_p++; - + if (EQ (type, Qfile)) - return unbind_to (unbind_count, handle_file_dialog_box (f, keys)); + return unbind_to_1 (unbind_count, handle_file_dialog_box (f, keys)); else if (EQ (type, Qdirectory)) - return unbind_to (unbind_count, handle_directory_dialog_box (f, keys)); + return unbind_to_1 (unbind_count, handle_directory_dialog_box (f, keys)); else if (EQ (type, Qquestion)) - return unbind_to (unbind_count, handle_question_dialog_box (f, keys)); + return unbind_to_1 (unbind_count, handle_question_dialog_box (f, keys)); else if (EQ (type, Qprint)) - return unbind_to (unbind_count, mswindows_handle_print_dialog_box (f, keys)); + return unbind_to_1 (unbind_count, + mswindows_handle_print_dialog_box (f, keys)); else if (EQ (type, Qpage_setup)) - return unbind_to (unbind_count, - mswindows_handle_page_setup_dialog_box (f, keys)); + return unbind_to_1 (unbind_count, + mswindows_handle_page_setup_dialog_box (f, keys)); else signal_error (Qunimplemented, "Dialog box type", type); return Qnil; @@ -830,7 +810,7 @@ syms_of_dialog_mswindows (void) { INIT_LRECORD_IMPLEMENTATION (mswindows_dialog_id); - + DEFKEYWORD (Q_initial_directory); DEFKEYWORD (Q_initial_filename); DEFKEYWORD (Q_filter_list); @@ -841,7 +821,7 @@ DEFKEYWORD (Q_file_must_exist); DEFKEYWORD (Q_no_network_button); DEFKEYWORD (Q_no_read_only_return); - + /* Errors */ DEFERROR_STANDARD (Qdialog_box_error, Qgui_error); } @@ -851,17 +831,17 @@ { Vpopup_frame_list = Qnil; staticpro (&Vpopup_frame_list); - + Vdialog_data_list = Qnil; staticpro (&Vdialog_data_list); - + DEFVAR_LISP ("default-file-dialog-filter-alist", &Vdefault_file_dialog_filter_alist /* -*/ ); + */ ); Vdefault_file_dialog_filter_alist = - list5 (Fcons (build_string ("Text Files"), build_string ("*.txt")), - Fcons (build_string ("C Files"), build_string ("*.c;*.h")), - Fcons (build_string ("Elisp Files"), build_string ("*.el")), - Fcons (build_string ("HTML Files"), build_string ("*.html;*.html")), - Fcons (build_string ("All Files"), build_string ("*.*"))); + list5 (Fcons (build_msg_string ("Text Files"), build_string ("*.txt")), + Fcons (build_msg_string ("C Files"), build_string ("*.c;*.h")), + Fcons (build_msg_string ("Elisp Files"), build_string ("*.el")), + Fcons (build_msg_string ("HTML Files"), build_string ("*.html;*.html")), + Fcons (build_msg_string ("All Files"), build_string ("*.*"))); }