add save file dialog (WinUI3) newapi

Mon, 12 Feb 2024 17:32:47 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 12 Feb 2024 17:32:47 +0100
branch
newapi
changeset 256
8874a68bafb0
parent 255
ebdce2bb62be
child 257
a334f9ebc5d0

add save file dialog (WinUI3)

ui/ui/window.h file | annotate | diff | comparison | revisions
ui/winui/window.cpp file | annotate | diff | comparison | revisions
--- a/ui/ui/window.h	Sun Feb 11 22:24:50 2024 +0100
+++ b/ui/ui/window.h	Mon Feb 12 17:32:47 2024 +0100
@@ -60,7 +60,7 @@
 UIEXPORT void ui_dialog_create(UiObject *parent, UiDialogArgs args);
 
 UIEXPORT void ui_openfiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata);
-UIEXPORT void ui_savefiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata);
+UIEXPORT void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata);
 
 
 
--- a/ui/winui/window.cpp	Sun Feb 11 22:24:50 2024 +0100
+++ b/ui/winui/window.cpp	Mon Feb 12 17:32:47 2024 +0100
@@ -46,6 +46,10 @@
 #include "MainWindow.xaml.h"
 
 
+#include <Windows.h>
+#include <shobjidl.h>
+#include <iostream>
+
 using namespace winrt;
 using namespace Microsoft::UI::Xaml;
 using namespace Microsoft::UI::Xaml::Controls;
@@ -357,6 +361,59 @@
 	}
 }
 
+static Windows::Foundation::IAsyncAction save_filedialog_async(UiObject *obj, char *name, ui_callback file_selected_callback, void *cbdata) {
+	IFileSaveDialog *saveFileDialog;
+
+	HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, IID_IFileSaveDialog, reinterpret_cast<void**>(&saveFileDialog));
+	if (FAILED(hr))
+	{
+		co_return;
+	}
+
+	if (name) {
+		wchar_t *wname = str2wstr(name, NULL);
+		saveFileDialog->SetFileName(wname);
+		free(wname);
+		free(name);
+	}
+	
+
+	hr = saveFileDialog->Show(NULL);
+	if (SUCCEEDED(hr)) {
+		IShellItem *item;
+		hr = saveFileDialog->GetResult(&item);
+		if (SUCCEEDED(hr)) {
+			PWSTR wpath;
+			hr = item->GetDisplayName(SIGDN_FILESYSPATH, &wpath);
+
+			if (SUCCEEDED(hr)) {
+				char *path = wchar2utf8(wpath, lstrlen(wpath));
+				CoTaskMemFree(wpath);
+
+				UiFileList flist;
+				flist.nfiles = 1;
+				flist.files = new char*[1];
+				flist.files[0] = path;
+
+				UiEvent evt;
+				evt.obj = obj;
+				evt.document = obj->ctx->document;
+				evt.window = obj->window;
+				evt.eventdata = &flist;
+				evt.intval = 0;
+				file_selected_callback(&evt, cbdata);
+
+				free(path);
+				delete[] flist.files;
+			}
+			item->Release();
+		}
+	}
+
+	// cleanup
+	saveFileDialog->Release();
+}
+
 static Windows::Foundation::IAsyncAction folderdialog_async(UiObject *obj, ui_callback file_selected_callback, void *cbdata) {
 	FolderPicker folderPicker = FolderPicker();
 	auto initializeWithWindow { folderPicker.as<::IInitializeWithWindow>()
@@ -396,6 +453,7 @@
 	}
 }
 
-UIEXPORT void ui_savefiledialog(UiObject *obj, unsigned int mode, ui_callback file_selected_callback, void *cbdata) {
-
+UIEXPORT void ui_savefiledialog(UiObject *obj, const char *name, ui_callback file_selected_callback, void *cbdata) {
+	char *n = name ? _strdup(name) : NULL;
+	save_filedialog_async(obj, n, file_selected_callback, cbdata);
 }

mercurial