getFile method
Returns a File
object from the selected file.
Returns null
if the user cancels the dialog.
Implementation
File? getFile() {
var didUserCancel = false;
var filePath = '';
final fileDialog = FileSaveDialog.createInstance();
using((arena) {
final pfos = arena<Uint32>();
var hr = fileDialog.getOptions(pfos);
if (FAILED(hr)) throw WindowsException(hr);
var options = pfos.value;
if (!addToRecentDocuments) {
options |= FILEOPENDIALOGOPTIONS.FOS_DONTADDTORECENT;
}
if (!dereferenceLinks) {
options |= FILEOPENDIALOGOPTIONS.FOS_NODEREFERENCELINKS;
}
if (fileMustExist) {
options |= FILEOPENDIALOGOPTIONS.FOS_FILEMUSTEXIST;
}
if (forceFileSystemItems) {
options |= FILEOPENDIALOGOPTIONS.FOS_FORCEFILESYSTEM;
}
if (hidePinnedPlaces) {
options |= FILEOPENDIALOGOPTIONS.FOS_HIDEPINNEDPLACES;
}
if (isDirectoryFixed) {
options |= FILEOPENDIALOGOPTIONS.FOS_NOCHANGEDIR;
}
if (showHiddenAndSystemItems) {
options |= FILEOPENDIALOGOPTIONS.FOS_FORCESHOWHIDDEN;
}
hr = fileDialog.setOptions(options);
if (FAILED(hr)) throw WindowsException(hr);
if (defaultExtension case final defaultExtension?
when defaultExtension.isNotEmpty) {
final pDefaultExtension =
defaultExtension.toNativeUtf16(allocator: arena);
final hr = fileDialog.setDefaultExtension(pDefaultExtension);
if (FAILED(hr)) throw WindowsException(hr);
}
if (fileName.isNotEmpty) {
final pFilename = fileName.toNativeUtf16(allocator: arena);
final hr = fileDialog.setFileName(pFilename);
if (FAILED(hr)) throw WindowsException(hr);
}
if (fileNameLabel.isNotEmpty) {
final pFileNameLabel = fileNameLabel.toNativeUtf16(allocator: arena);
final hr = fileDialog.setFileNameLabel(pFileNameLabel);
if (FAILED(hr)) throw WindowsException(hr);
}
if (title.isNotEmpty) {
final pTitle = title.toNativeUtf16(allocator: arena);
final hr = fileDialog.setTitle(pTitle);
if (FAILED(hr)) throw WindowsException(hr);
}
if (filterSpecification.isNotEmpty) {
final rgSpec = arena<COMDLG_FILTERSPEC>(filterSpecification.length);
var index = 0;
for (final key in filterSpecification.keys) {
final pszName = key.toNativeUtf16(allocator: arena);
final pszSpec =
filterSpecification[key]!.toNativeUtf16(allocator: arena);
rgSpec[index]
..pszName = pszName
..pszSpec = pszSpec;
index++;
}
final hr = fileDialog.setFileTypes(filterSpecification.length, rgSpec);
if (FAILED(hr)) throw WindowsException(hr);
}
if (initialDirectory case final initialDirectory?
when initialDirectory.isNotEmpty) {
final pszPath = initialDirectory.toNativeUtf16(allocator: arena);
final riid = convertToIID(IID_IShellItem, allocator: arena);
final ppv = calloc<Pointer>();
var hr = SHCreateItemFromParsingName(
pszPath,
nullptr,
riid,
ppv,
);
if (FAILED(hr)) throw WindowsException(hr);
final shellItem = IShellItem(ppv.cast());
hr = alwaysShowInitialDirectory
? fileDialog
.setFolder(shellItem.ptr.cast<Pointer<COMObject>>().value)
: fileDialog.setDefaultFolder(
shellItem.ptr.cast<Pointer<COMObject>>().value);
if (FAILED(hr)) throw WindowsException(hr);
}
hr = fileDialog.show(hWndOwner);
if (!SUCCEEDED(hr)) {
if (hr == HRESULT_FROM_WIN32(WIN32_ERROR.ERROR_CANCELLED)) {
didUserCancel = true;
} else {
throw WindowsException(hr);
}
} else {
final ppsi = calloc<Pointer<COMObject>>();
var hr = fileDialog.getResult(ppsi);
if (FAILED(hr)) throw WindowsException(hr);
using((arena) {
final item = IShellItem(ppsi.cast());
final ppszName = arena<Pointer<Utf16>>();
hr = item.getDisplayName(SIGDN.SIGDN_FILESYSPATH, ppszName);
if (FAILED(hr)) throw WindowsException(hr);
filePath = ppszName.value.toDartString();
});
}
});
return didUserCancel ? null : File(filePath);
}