@@ 22,10 22,12 @@ var (
_GetOpenFileName = _Dialog32.NewProc("GetOpenFileNameW")
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew
- _FlagFileMustExist = uint32(0x00001000)
- _FlagForceShowHidden = uint32(0x10000000)
- _FlagOverwritePrompt = uint32(0x00000002)
- _FlagDisableLinks = uint32(0x00100000)
+ _FlagFileMustExist = uint32(0x00001000)
+ _FlagForceShowHidden = uint32(0x10000000)
+ _FlagOverwritePrompt = uint32(0x00000002)
+ _FlagDisableLinks = uint32(0x00100000)
+ _FlagAllowMultiSelect = uint32(0x00000200)
+ _FlagExplorer = uint32(0x00080000)
_FilePathLength = uint32(65535)
_OpenFileStructLength = uint32(unsafe.Sizeof(_OpenFileName{}))
@@ 118,8 120,61 @@ func (e *Explorer) importFile(extensions ...string) (io.ReadCloser, error) {
return os.Open(path)
}
-func (e *Explorer) importFiles(_ ...string) ([]io.ReadCloser, error) {
- return nil, ErrNotAvailable
+func (e *Explorer) importFiles(extensions ...string) ([]io.ReadCloser, error) {
+ pathUTF16 := make([]uint16, _FilePathLength)
+
+ open := _OpenFileName{
+ File: &pathUTF16[0],
+ MaxFile: _FilePathLength,
+ Filter: buildFilter(extensions),
+ Flags: _FlagFileMustExist | _FlagForceShowHidden | _FlagDisableLinks | _FlagAllowMultiSelect | _FlagExplorer,
+ StructSize: _OpenFileStructLength,
+ }
+
+ if r, _, _ := _GetOpenFileName.Call(uintptr(unsafe.Pointer(&open))); r == 0 {
+ return nil, ErrUserDecline
+ }
+
+ // Split the pathUTF16 by null characters
+ paths := make([]string, 0)
+ currentPath := make([]uint16, 0)
+ for _, char := range pathUTF16 {
+ if char == 0 {
+ if len(currentPath) > 0 {
+ paths = append(paths, windows.UTF16ToString(currentPath))
+ currentPath = currentPath[:0]
+ }
+ } else {
+ currentPath = append(currentPath, char)
+ }
+ }
+
+ // The first element is the directory, append it to each filename
+ dir := paths[0]
+ filePaths := make([]string, len(paths)-1)
+ for i, file := range paths[1:] {
+ filePaths[i] = filepath.Join(dir, file)
+ }
+
+ if len(filePaths) == 0 {
+ return nil, ErrUserDecline
+ }
+
+ files := make([]io.ReadCloser, len(filePaths))
+ for i, filePath := range filePaths {
+ file, err := os.Open(filePath)
+ if err != nil {
+ for _, file := range files {
+ if file != nil {
+ file.Close()
+ }
+ }
+ return nil, err
+ }
+ files[i] = file
+ }
+
+ return files, nil
}
func buildFilter(extensions []string) *uint16 {