static Lisp_Object Q_initial_directory;
static Lisp_Object Q_initial_filename;
static Lisp_Object Q_filter_list;
+/* Declared in general-slots.h
static Lisp_Object Q_title;
+*/
static Lisp_Object Q_allow_multi_select;
static Lisp_Object Q_create_prompt_on_nonexistent;
static Lisp_Object Q_overwrite_prompt;
LIST_LOOP_2 (popup, Vpopup_frame_list)
{
HWND hwnd = FRAME_MSWINDOWS_HANDLE (XFRAME (popup));
+ /* This is a windows feature that allows dialog type
+ processing to be applied to standard windows containing
+ controls. */
if (IsDialogMessage (hwnd, msg))
return 1;
}
return arg;
}
+/* Unwind protection decrements dialog count */
+static Lisp_Object
+dialog_popped_down (Lisp_Object arg)
+{
+ popup_up_p--;
+ return Qnil;
+}
+
#define ALIGN_TEMPLATE \
{ \
{ FRERR_BUFFERLENGTHZERO, "FRERR_BUFFERLENGTHZERO" },
};
+struct param_data {
+ char* fname;
+ char* unknown_fname;
+ int validate;
+};
+
+static int
+CALLBACK handle_directory_proc (HWND hwnd, UINT msg,
+ LPARAM lParam, LPARAM lpData)
+{
+ TCHAR szDir[MAX_PATH];
+ 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);
+ }
+ break;
+
+ case BFFM_VALIDATEFAILED:
+ if (pd->validate)
+ return TRUE;
+ else
+ pd->unknown_fname = xstrdup((char*)lParam);
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Lisp_Object
+handle_directory_dialog_box (struct frame *f, Lisp_Object keys)
+{
+ Lisp_Object ret = Qnil;
+ BROWSEINFO bi;
+ LPITEMIDLIST pidl;
+ LPMALLOC pMalloc;
+ struct param_data 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.lpfn = handle_directory_proc;
+
+ LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (build_string (""), Qnil),
+ pd.fname);
+
+ {
+ EXTERNAL_PROPERTY_LIST_LOOP_3 (key, value, keys)
+ {
+ if (EQ (key, Q_title))
+ {
+ CHECK_STRING (value);
+ LISP_STRING_TO_EXTERNAL (value, bi.lpszTitle, Qmswindows_tstr);
+ }
+ else if (EQ (key, Q_initial_directory))
+ LOCAL_FILE_FORMAT_TO_TSTR (Fexpand_file_name (value, Qnil),
+ pd.fname);
+ else if (EQ (key, Q_initial_filename))
+ ; /* do nothing */
+ else if (EQ (key, Q_file_must_exist))
+ {
+ if (!NILP (value)) {
+ pd.validate = TRUE;
+ bi.ulFlags |= BIF_VALIDATE;
+ }
+ else
+ bi.ulFlags &= ~BIF_VALIDATE;
+ }
+ else
+ syntax_error ("Unrecognized directory dialog keyword", key);
+ }
+ }
+
+ 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);
+ }
+
+ 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 while (1)
+ signal_quit ();
+ }
+ else
+ signal_type_error (Qdialog_box_error,
+ "Unable to create folder browser",
+ make_int (0));
+ return ret;
+}
+
static Lisp_Object
handle_file_dialog_box (struct frame *f, Lisp_Object keys)
{
OPENFILENAME ofn;
+
char fnbuf[8000];
xzero (ofn);
ofn.lStructSize = sizeof (ofn);
+ ofn.Flags = OFN_EXPLORER;
ofn.hwndOwner = FRAME_MSWINDOWS_HANDLE (f);
ofn.lpstrFile = fnbuf;
ofn.nMaxFile = sizeof (fnbuf) / XETCHAR_SIZE;
mswindows_make_dialog_box_internal (struct frame* f, Lisp_Object type,
Lisp_Object keys)
{
+ int unbind_count = specpdl_depth ();
+ record_unwind_protect (dialog_popped_down, Qnil);
+ popup_up_p++;
+
if (EQ (type, Qfile))
- return handle_file_dialog_box (f, keys);
+ return unbind_to (unbind_count, handle_file_dialog_box (f, keys));
+ else if (EQ (type, Qdirectory))
+ return unbind_to (unbind_count, handle_directory_dialog_box (f, keys));
else if (EQ (type, Qquestion))
- return handle_question_dialog_box (f, keys);
+ return unbind_to (unbind_count, handle_question_dialog_box (f, keys));
else if (EQ (type, Qprint))
- return mswindows_handle_print_dialog_box (f, keys);
+ return unbind_to (unbind_count, mswindows_handle_print_dialog_box (f, keys));
else if (EQ (type, Qpage_setup))
- return mswindows_handle_page_setup_dialog_box (f, keys);
- else if (EQ (type, Qprint_setup))
- return mswindows_handle_print_setup_dialog_box (f, keys);
+ return unbind_to (unbind_count,
+ mswindows_handle_page_setup_dialog_box (f, keys));
else
signal_type_error (Qunimplemented, "Dialog box type", type);
return Qnil;