1 /* Implements elisp-programmable dialog boxes -- MS Windows interface.
2 Copyright (C) 1998 Kirill M. Katsnelson <kkm@kis.ru>
3 Copyright (C) 2000 Ben Wing.
5 This file is part of XEmacs.
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Synched up with: Not in FSF. */
25 Initially written by kkm, May 1998
32 #include "console-msw.h"
40 Lisp_Object Qdialog_box_error;
42 static Lisp_Object Q_initial_directory;
43 static Lisp_Object Q_initial_filename;
44 static Lisp_Object Q_filter_list;
45 static Lisp_Object Q_title;
46 static Lisp_Object Q_allow_multi_select;
47 static Lisp_Object Q_create_prompt_on_nonexistent;
48 static Lisp_Object Q_overwrite_prompt;
49 static Lisp_Object Q_file_must_exist;
50 static Lisp_Object Q_no_network_button;
51 static Lisp_Object Q_no_read_only_return;
53 /* List containing all dialog data structures of currently popped up
55 static Lisp_Object Vdialog_data_list;
57 /* List of popup frames wanting keyboard traversal handled */
58 static Lisp_Object Vpopup_frame_list;
60 Lisp_Object Vdefault_file_dialog_filter_alist;
62 /* DLUs per character metrics */
63 #define X_DLU_PER_CHAR 4
64 #define Y_DLU_PER_CHAR 8
69 All buttons have height of 15 DLU. The minimum width for a button is 32 DLU,
70 but it can be expanded to accommodate its text, so the width is calculated as
71 8 DLU per button plus 4 DLU per character.
72 max (32, 6 * text_length). The factor of six is rather empirical, but it
73 works better than 8 which comes from the definition of a DLU. Buttons are
74 spaced with 6 DLU gap. Minimum distance from the button to the left or right
75 dialog edges is 6 DLU, and the distance between the dialog bottom edge and
79 #define X_MIN_BUTTON 32
80 #define X_BUTTON_MARGIN 8
82 #define X_BUTTON_SPACING 6
83 #define X_BUTTON_FROM_EDGE 6
84 #define Y_BUTTON_FROM_EDGE 7
89 Text distance from left and right edges is the same as for buttons, and the
90 top margin is 11 DLU. The static control has height of 2 DLU per control
91 plus 8 DLU per each line of text. Distance between the bottom edge of the
92 control and the button row is 15 DLU. Minimum width of the static control
93 is 100 DLU, thus giving minimum dialog weight of 112 DLU. Maximum width is
94 300 DLU, and, if the text is wider than that, the text is wrapped on the
95 next line. Each character in the text is considered 4 DLU wide.
98 #define X_MIN_TEXT 100
99 #define X_AVE_TEXT 200
100 #define X_MAX_TEXT 300
101 #define X_TEXT_FROM_EDGE X_BUTTON_FROM_EDGE
102 #define Y_TEXT_FROM_EDGE 11
103 #define Y_TEXT_MARGIN 2
104 #define Y_TEXT_FROM_BUTTON 15
106 #define X_MIN_TEXT_CHAR (X_MIN_TEXT / X_DLU_PER_CHAR)
107 #define X_AVE_TEXT_CHAR (X_AVE_TEXT / X_DLU_PER_CHAR)
108 #define X_MAX_TEXT_CHAR (X_MAX_TEXT / X_DLU_PER_CHAR)
113 First we calculate the minimum width of the button row, excluding "from
114 edge" distances. Note that the static control text can be narrower than
115 X_AVE_TEXT only if both text and button row are narrower than that (so,
116 even if text *can* be wrapped into 2 rows narrower than ave width, it is not
117 done). Let WBR denote the width of the button row.
119 Next, the width of the static field is determined.
120 First, if all lines of text fit into max (WBR, X_MAX_TEXT), the width of the
121 control is the same as the width of the longest line.
122 Second, if all lines of text are narrower than X_MIN_TEXT, then width of
123 the control is set to X_MIN_TEXT.
124 Otherwise, width is set to max(WBR, X_AVE_TEXT). In this case, line wrapping will
127 If width of the text control is larger than that of the button row, then the
128 latter is centered across the dialog, by giving it extra edge
129 margins. Otherwise, minimal margins are given to the button row.
132 #define ID_ITEM_BIAS 32
135 mswindows_register_popup_frame (Lisp_Object frame)
137 Vpopup_frame_list = Fcons (frame, Vpopup_frame_list);
141 mswindows_unregister_popup_frame (Lisp_Object frame)
143 Vpopup_frame_list = delq_no_quit (frame, Vpopup_frame_list);
146 /* Dispatch message to any dialog boxes. Return non-zero if dispatched. */
148 mswindows_is_dialog_msg (MSG *msg)
150 LIST_LOOP_2 (data, Vdialog_data_list)
152 if (IsDialogMessage (XMSWINDOWS_DIALOG_ID (data)->hwnd, msg))
157 LIST_LOOP_2 (popup, Vpopup_frame_list)
159 HWND hwnd = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
160 /* This is a windows feature that allows dialog type
161 processing to be applied to standard windows containing
163 if (IsDialogMessage (hwnd, msg))
171 mark_mswindows_dialog_id (Lisp_Object obj)
173 struct mswindows_dialog_id *data = XMSWINDOWS_DIALOG_ID (obj);
174 mark_object (data->frame);
175 return data->callbacks;
178 DEFINE_LRECORD_IMPLEMENTATION ("mswindows-dialog-id", mswindows_dialog_id,
179 mark_mswindows_dialog_id, 0, 0, 0, 0, 0,
180 struct mswindows_dialog_id);
182 /* Dialog procedure */
184 dialog_proc (HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
189 SetWindowLong (hwnd, DWL_USER, l_param);
195 VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER));
196 Vdialog_data_list = delq_no_quit (data, Vdialog_data_list);
202 Lisp_Object fn, arg, data;
203 struct mswindows_dialog_id *did;
205 VOID_TO_LISP (data, GetWindowLong (hwnd, DWL_USER));
206 did = XMSWINDOWS_DIALOG_ID (data);
207 if (w_param != IDCANCEL) /* user pressed escape */
209 assert (w_param >= ID_ITEM_BIAS
211 < XVECTOR_LENGTH (did->callbacks) + ID_ITEM_BIAS);
213 get_gui_callback (XVECTOR_DATA (did->callbacks)
214 [w_param - ID_ITEM_BIAS],
216 mswindows_enqueue_misc_user_event (did->frame, fn, arg);
219 mswindows_enqueue_misc_user_event (did->frame, Qrun_hooks,
220 Qmenu_no_selection_hook);
221 /* #### need to error-protect! will do so when i merge in
223 va_run_hook_with_args (Qdelete_dialog_box_hook, 1, data);
225 DestroyWindow (hwnd);
235 /* Helper function which converts the supplied string STRING into Unicode and
236 pushes it at the end of DYNARR */
238 push_lisp_string_as_unicode (unsigned_char_dynarr* dynarr, Lisp_Object string)
240 Extbyte *mbcs_string;
241 Charcount length = XSTRING_CHAR_LENGTH (string);
244 TO_EXTERNAL_FORMAT (LISP_STRING, string,
245 C_STRING_ALLOCA, mbcs_string,
247 uni_string = alloca_array (WCHAR, length + 1);
248 length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1,
249 uni_string, sizeof(WCHAR) * (length + 1));
250 Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length);
253 /* Helper function which converts the supplied string STRING into Unicode and
254 pushes it at the end of DYNARR */
256 push_bufbyte_string_as_unicode (unsigned_char_dynarr* dynarr, Bufbyte *string,
259 Extbyte *mbcs_string;
260 Charcount length = bytecount_to_charcount (string, len);
263 TO_EXTERNAL_FORMAT (C_STRING, string,
264 C_STRING_ALLOCA, mbcs_string,
266 uni_string = alloca_array (WCHAR, length + 1);
267 length = MultiByteToWideChar (CP_ACP, 0, mbcs_string, -1,
268 uni_string, sizeof(WCHAR) * (length + 1));
269 Dynarr_add_many (dynarr, uni_string, sizeof(WCHAR) * length);
272 /* Given button TEXT, return button width in DLU */
274 button_width (Lisp_Object text)
276 unsigned int width = X_DLU_PER_CHAR * XSTRING_CHAR_LENGTH (text);
277 return max (X_MIN_BUTTON, width);
280 /* Unwind protection routine frees a dynarr opaqued into arg */
282 free_dynarr_opaque_ptr (Lisp_Object arg)
284 Dynarr_free (get_opaque_ptr (arg));
289 #define ALIGN_TEMPLATE \
291 unsigned int slippage = Dynarr_length (template) & 3; \
293 Dynarr_add_many (template, &zeroes, slippage); \
300 } common_dialog_errors[] =
302 { CDERR_DIALOGFAILURE, "CDERR_DIALOGFAILURE" },
303 { CDERR_FINDRESFAILURE, "CDERR_FINDRESFAILURE" },
304 { CDERR_INITIALIZATION, "CDERR_INITIALIZATION" },
305 { CDERR_LOADRESFAILURE, "CDERR_LOADRESFAILURE" },
306 { CDERR_LOADSTRFAILURE, "CDERR_LOADSTRFAILURE" },
307 { CDERR_LOCKRESFAILURE, "CDERR_LOCKRESFAILURE" },
308 { CDERR_MEMALLOCFAILURE, "CDERR_MEMALLOCFAILURE" },
309 { CDERR_MEMLOCKFAILURE, "CDERR_MEMLOCKFAILURE" },
310 { CDERR_NOHINSTANCE, "CDERR_NOHINSTANCE" },
311 { CDERR_NOHOOK, "CDERR_NOHOOK" },
312 { CDERR_NOTEMPLATE, "CDERR_NOTEMPLATE" },
313 { CDERR_REGISTERMSGFAIL, "CDERR_REGISTERMSGFAIL" },
314 { CDERR_STRUCTSIZE, "CDERR_STRUCTSIZE" },
315 { PDERR_CREATEICFAILURE, "PDERR_CREATEICFAILURE" },
316 { PDERR_DEFAULTDIFFERENT, "PDERR_DEFAULTDIFFERENT" },
317 { PDERR_DNDMMISMATCH, "PDERR_DNDMMISMATCH" },
318 { PDERR_GETDEVMODEFAIL, "PDERR_GETDEVMODEFAIL" },
319 { PDERR_INITFAILURE, "PDERR_INITFAILURE" },
320 { PDERR_LOADDRVFAILURE, "PDERR_LOADDRVFAILURE" },
321 { PDERR_NODEFAULTPRN, "PDERR_NODEFAULTPRN" },
322 { PDERR_NODEVICES, "PDERR_NODEVICES" },
323 { PDERR_PARSEFAILURE, "PDERR_PARSEFAILURE" },
324 { PDERR_PRINTERNOTFOUND, "PDERR_PRINTERNOTFOUND" },
325 { PDERR_RETDEFFAILURE, "PDERR_RETDEFFAILURE" },
326 { PDERR_SETUPFAILURE, "PDERR_SETUPFAILURE" },
327 { CFERR_MAXLESSTHANMIN, "CFERR_MAXLESSTHANMIN" },
328 { CFERR_NOFONTS, "CFERR_NOFONTS" },
329 { FNERR_BUFFERTOOSMALL, "FNERR_BUFFERTOOSMALL" },
330 { FNERR_INVALIDFILENAME, "FNERR_INVALIDFILENAME" },
331 { FNERR_SUBCLASSFAILURE, "FNERR_SUBCLASSFAILURE" },
332 { FRERR_BUFFERLENGTHZERO, "FRERR_BUFFERLENGTHZERO" },
336 handle_file_dialog_box (struct frame *f, Lisp_Object keys)
342 ofn.lStructSize = sizeof (ofn);
343 ofn.hwndOwner = FRAME_MSWINDOWS_HANDLE (f);
344 ofn.lpstrFile = fnbuf;
345 ofn.nMaxFile = sizeof (fnbuf) / XETCHAR_SIZE;
346 xetcscpy (fnbuf, XETEXT (""));
348 LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (build_string (""), Qnil),
349 ofn.lpstrInitialDir);
352 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
354 if (EQ (key, Q_initial_filename))
358 CHECK_STRING (value);
359 LOCAL_FILE_FORMAT_TO_TSTR (value, fnout);
360 xetcscpy (fnbuf, fnout);
362 else if (EQ (key, Q_title))
364 CHECK_STRING (value);
365 LISP_STRING_TO_EXTERNAL (value, ofn.lpstrTitle, Qmswindows_tstr);
367 else if (EQ (key, Q_initial_directory))
368 LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (value, Qnil),
369 ofn.lpstrInitialDir);
370 else if (EQ (key, Q_file_must_exist))
373 ofn.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
375 ofn.Flags &= ~(OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST);
378 syntax_error ("Unrecognized file-dialog keyword", key);
382 if (!GetOpenFileName (&ofn))
384 DWORD err = CommDlgExtendedError ();
394 for (i = 0; i < countof (common_dialog_errors); i++)
396 if (common_dialog_errors[i].errmess == err)
397 signal_type_error (Qdialog_box_error,
398 "Creating file-dialog-box",
400 (common_dialog_errors[i].errname));
403 signal_type_error (Qdialog_box_error,
404 "Unknown common dialog box error???",
409 return tstr_to_local_file_format (ofn.lpstrFile);
413 handle_question_dialog_box (struct frame *f, Lisp_Object keys)
415 Lisp_Object_dynarr *dialog_items = Dynarr_new (Lisp_Object);
416 unsigned_char_dynarr *template = Dynarr_new (unsigned_char);
417 unsigned int button_row_width = 0;
418 unsigned int text_width, text_height;
419 Lisp_Object question = Qnil, title = Qnil;
421 int unbind_count = specpdl_depth ();
422 record_unwind_protect (free_dynarr_opaque_ptr,
423 make_opaque_ptr (dialog_items));
424 record_unwind_protect (free_dynarr_opaque_ptr,
425 make_opaque_ptr (template));
427 /* A big NO NEED to GCPRO gui_items stored in the array: they are just
428 pointers into KEYS list, which is GC-protected by the caller */
431 EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
433 if (EQ (key, Q_question))
435 CHECK_STRING (value);
438 else if (EQ (key, Q_title))
440 CHECK_STRING (value);
443 else if (EQ (key, Q_buttons))
445 Lisp_Object item_cons;
447 /* Parse each item in the dialog into gui_item structs,
448 and stuff a dynarr of these. Calculate button row width
450 EXTERNAL_LIST_LOOP (item_cons, value)
452 if (!NILP (XCAR (item_cons)))
455 gui_parse_item_keywords (XCAR (item_cons));
456 Dynarr_add (dialog_items, gitem);
457 button_row_width += button_width (XGUI_ITEM (gitem)->name)
462 button_row_width -= X_BUTTON_MARGIN;
465 syntax_error ("Unrecognized question-dialog keyword", key);
469 if (Dynarr_length (dialog_items) == 0)
470 syntax_error ("Dialog descriptor provides no buttons", keys);
473 syntax_error ("Dialog descriptor provides no question", keys);
475 /* Determine the final width layout */
477 Bufbyte *p = XSTRING_DATA (question);
478 Charcount string_max = 0, this_length = 0;
481 Emchar ch = charptr_emchar (p);
484 if (ch == (Emchar)'\n' || ch == (Emchar)'\0')
486 string_max = max (this_length, string_max);
492 if (ch == (Emchar)'\0')
496 if (string_max * X_DLU_PER_CHAR > max (X_MAX_TEXT, button_row_width))
497 text_width = X_AVE_TEXT;
498 else if (string_max * X_DLU_PER_CHAR < X_MIN_TEXT)
499 text_width = X_MIN_TEXT;
501 text_width = string_max * X_DLU_PER_CHAR;
502 text_width = max (text_width, button_row_width);
505 /* Now calculate the height for the text control */
507 Bufbyte *p = XSTRING_DATA (question);
508 Charcount break_at = text_width / X_DLU_PER_CHAR;
509 Charcount char_pos = 0;
513 while ((ch = charptr_emchar (p)) != (Emchar) '\0')
516 char_pos += ch != (Emchar) '\n';
517 if (ch == (Emchar) '\n' || char_pos == break_at)
523 text_height = Y_TEXT_MARGIN + Y_DLU_PER_CHAR * num_lines;
526 /* Ok, now we are ready to stuff the dialog template and lay out controls */
529 DLGITEMTEMPLATE item_tem;
531 const unsigned int zeroes = 0;
532 const unsigned int ones = 0xFFFFFFFF;
533 const WORD static_class_id = 0x0082;
534 const WORD button_class_id = 0x0080;
536 /* Create and stuff in DLGTEMPLATE header */
537 dlg_tem.style = (DS_CENTER | DS_MODALFRAME | DS_SETFONT
538 | WS_CAPTION | WS_POPUP | WS_VISIBLE);
539 dlg_tem.dwExtendedStyle = 0;
540 dlg_tem.cdit = Dynarr_length (dialog_items) + 1;
543 dlg_tem.cx = text_width + 2 * X_TEXT_FROM_EDGE;
544 dlg_tem.cy = (Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON
545 + Y_BUTTON + Y_BUTTON_FROM_EDGE);
546 Dynarr_add_many (template, &dlg_tem, sizeof (dlg_tem));
548 /* We want no menu and standard class */
549 Dynarr_add_many (template, &zeroes, 4);
551 /* And the third is the dialog title. "XEmacs" unless one is supplied.
552 Note that the string must be in Unicode. */
554 Dynarr_add_many (template, L"XEmacs", 14);
556 push_lisp_string_as_unicode (template, title);
558 /* We want standard dialog font */
559 Dynarr_add_many (template, L"\x08MS Shell Dlg", 28);
561 /* Next add text control. */
562 item_tem.style = WS_CHILD | WS_VISIBLE | SS_LEFT | SS_NOPREFIX;
563 item_tem.dwExtendedStyle = 0;
564 item_tem.x = X_TEXT_FROM_EDGE;
565 item_tem.y = Y_TEXT_FROM_EDGE;
566 item_tem.cx = text_width;
567 item_tem.cy = text_height;
568 item_tem.id = 0xFFFF;
571 Dynarr_add_many (template, &item_tem, sizeof (item_tem));
573 /* Right after class id follows */
574 Dynarr_add_many (template, &ones, 2);
575 Dynarr_add_many (template, &static_class_id, sizeof (static_class_id));
577 /* Next thing to add is control text, as Unicode string */
578 push_lisp_string_as_unicode (template, question);
580 /* Specify 0 length creation data */
581 Dynarr_add_many (template, &zeroes, 2);
583 /* Now it's the button time */
584 item_tem.y = Y_TEXT_FROM_EDGE + text_height + Y_TEXT_FROM_BUTTON;
585 item_tem.x = X_BUTTON_FROM_EDGE + (button_row_width < text_width
586 ? (text_width - button_row_width) / 2
588 item_tem.cy = Y_BUTTON;
589 item_tem.dwExtendedStyle = 0;
591 for (i = 0; i < Dynarr_length (dialog_items); ++i)
593 Lisp_Object* gui_item = Dynarr_atp (dialog_items, i);
594 Lisp_Gui_Item *pgui_item = XGUI_ITEM (*gui_item);
596 item_tem.style = (WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON
597 | (gui_item_active_p (*gui_item) ? 0 : WS_DISABLED));
598 item_tem.cx = button_width (pgui_item->name);
599 /* Item ids are indices into dialog_items plus offset, to avoid having
600 items by reserved ids (IDOK, IDCANCEL) */
601 item_tem.id = i + ID_ITEM_BIAS;
604 Dynarr_add_many (template, &item_tem, sizeof (item_tem));
606 /* Right after 0xFFFF and class id atom follows */
607 Dynarr_add_many (template, &ones, 2);
608 Dynarr_add_many (template, &button_class_id, sizeof (button_class_id));
610 /* Next thing to add is control text, as Unicode string */
612 Lisp_Object ctext = pgui_item->name;
614 Bufbyte *trans = (Bufbyte *) alloca (2 * XSTRING_LENGTH (ctext) + 3);
617 memcpy (trans, XSTRING_DATA (ctext), XSTRING_LENGTH (ctext) + 1);
619 mswindows_translate_menu_or_dialog_item (trans,
620 XSTRING_LENGTH (ctext),
621 2 * XSTRING_LENGTH (ctext) + 3,
624 push_bufbyte_string_as_unicode (template, trans, translen);
627 /* Specify 0 length creation data. */
628 Dynarr_add_many (template, &zeroes, 2);
630 item_tem.x += item_tem.cx + X_BUTTON_SPACING;
634 /* Now the Windows dialog structure is ready. We need to prepare a
635 data structure for the new dialog, which will contain callbacks
636 and the frame for these callbacks. This structure has to be
637 GC-protected and thus it is put into a statically protected
640 Lisp_Object dialog_data;
642 struct mswindows_dialog_id *did =
643 alloc_lcrecord_type (struct mswindows_dialog_id,
644 &lrecord_mswindows_dialog_id);
646 XSETMSWINDOWS_DIALOG_ID (dialog_data, did);
648 did->frame = wrap_frame (f);
649 did->callbacks = make_vector (Dynarr_length (dialog_items), Qunbound);
650 for (i = 0; i < Dynarr_length (dialog_items); i++)
651 XVECTOR_DATA (did->callbacks) [i] =
652 XGUI_ITEM (*Dynarr_atp (dialog_items, i))->callback;
654 /* Woof! Everything is ready. Pop pop pop in now! */
656 CreateDialogIndirectParam (NULL,
657 (LPDLGTEMPLATE) Dynarr_atp (template, 0),
658 FRAME_MSWINDOWS_HANDLE (f), dialog_proc,
659 (LPARAM) LISP_TO_VOID (dialog_data));
661 /* Something went wrong creating the dialog */
662 signal_type_error (Qdialog_box_error, "Creating dialog", keys);
664 Vdialog_data_list = Fcons (dialog_data, Vdialog_data_list);
666 /* Cease protection and free dynarrays */
667 unbind_to (unbind_count, Qnil);
673 mswindows_make_dialog_box_internal (struct frame* f, Lisp_Object type,
676 if (EQ (type, Qfile))
677 return handle_file_dialog_box (f, keys);
678 else if (EQ (type, Qquestion))
679 return handle_question_dialog_box (f, keys);
680 else if (EQ (type, Qprint))
681 return mswindows_handle_print_dialog_box (f, keys);
682 else if (EQ (type, Qpage_setup))
683 return mswindows_handle_page_setup_dialog_box (f, keys);
684 else if (EQ (type, Qprint_setup))
685 return mswindows_handle_print_setup_dialog_box (f, keys);
687 signal_type_error (Qunimplemented, "Dialog box type", type);
692 console_type_create_dialog_mswindows (void)
694 CONSOLE_HAS_METHOD (mswindows, make_dialog_box_internal);
698 syms_of_dialog_mswindows (void)
700 INIT_LRECORD_IMPLEMENTATION (mswindows_dialog_id);
702 DEFKEYWORD (Q_initial_directory);
703 DEFKEYWORD (Q_initial_filename);
704 DEFKEYWORD (Q_filter_list);
705 DEFKEYWORD (Q_title);
706 DEFKEYWORD (Q_allow_multi_select);
707 DEFKEYWORD (Q_create_prompt_on_nonexistent);
708 DEFKEYWORD (Q_overwrite_prompt);
709 DEFKEYWORD (Q_file_must_exist);
710 DEFKEYWORD (Q_no_network_button);
711 DEFKEYWORD (Q_no_read_only_return);
714 DEFERROR_STANDARD (Qdialog_box_error, Qinvalid_operation);
718 vars_of_dialog_mswindows (void)
720 Vpopup_frame_list = Qnil;
721 staticpro (&Vpopup_frame_list);
723 Vdialog_data_list = Qnil;
724 staticpro (&Vdialog_data_list);
726 DEFVAR_LISP ("default-file-dialog-filter-alist",
727 &Vdefault_file_dialog_filter_alist /*
729 Vdefault_file_dialog_filter_alist =
730 list5 (Fcons (build_string ("Text Files"), build_string ("*.txt")),
731 Fcons (build_string ("C Files"), build_string ("*.c;*.h")),
732 Fcons (build_string ("Elisp Files"), build_string ("*.el")),
733 Fcons (build_string ("HTML Files"), build_string ("*.html;*.html")),
734 Fcons (build_string ("All Files"), build_string ("*.*")));