Open tristanlabelle opened 10 months ago
Something like:
func main() {
let openFileWindow = NSOpenPanel()
openFileWindow.allowsMultipleSelection = false
openFileWindow.canChooseDirectories = false
if openFileWindow.runModal() == .OK {
guard let selectedFileURL = openFileWindow.url else {
return
}
let filePath = selectedFileURL.path
print("Selected file path: \(filePath)")
}
}
@Squidonomics NSOpenPanel
is part of AppKit
, which is macOS-specific. We can translate the C++ code above to Swift pretty much directly by using the WinSDK
module on Windows, which should expose GetOpenFileNameW
.
@tristanlabelle Ah more like this then?
import WinSDK
func main() {
var openFileWindow = openFileWindowW()
openFileWindow.lStructSize = UInt32(sizeof(openFileWindowW.self))
var filePath: [WCHAR] = Array(repeating: 0, count: 256)
openFileWindow.lpstrFile = &filePath
openFileWindow.nMaxFile = 256
if GetOpenFileNameW(&openFileWindow) != 0 {
guard let selectedFilePath = String(bytes: filePath, encoding: .unicode) else {
return
}
print("Selected file path: \(selectedFilePath)")
} else {
print("Error: Failed to open file selection dialog.")
}
}
Note that the use of the array that way is technically UB. This needs a tad bit more work to create the window and all, but should be mostly correct.
import WinSDK
internal var OFN_PATHMUSTEXIST: DWORD {
DWORD(WinSDK.OFN_PATHMUSTEXIST)
}
internal var OFN_FILEMUSTEXIST: DWORD {
DWORD(WinSDK.OFN_FILEMUSTEXIST)
}
internal var GENERIC_READ: DWORD {
DWORD(WinSDK.GENERIC_READ)
}
internal var OPEN_EXISTING: DWORD {
DWORD(WinSDK.OPEN_EXISTING)
}
internal var FILE_ATTRIBUTE_NORMAL: DWORD {
DWORD(WinSDK.FILE_ATTRIBUTE_NORMAL)
}
var ofn: OPENFILENAMEW = .init()
ofn.lStructSize = DWORD(MemoryLayout<OPENFILENAMEW>.size)
ofn.hwndOwner = ...
let hFile: HANDLE = withUnsafeTemporaryStorage(of: WCHAR.self, capacity: Int(MAX_PATH)) {
ofn.lpstrFile = $0.baseAddress
ofn.lpstrFile[0] = '\0'
ofn.nMaxFile = $0.count
ofn.lpstrFileTitle = nil
ofn.nMaxFileTitle = 0
ofn.lpstrInitialDir = nil
ofn.Flags = OFN_PATHMUSTEXIT | OFN_FILEMUSTEXIST
return "All\0.*\0Text\0*.TXT\0".withCString(encodedAs: UTF16.self) {
ofn.lpstrFilter = $0
ofn.nFilterIndex = 1
guard GetOpenFileName(&ofn) else { return INVALID_HANDLE }
return CreateFileW(ofn.lpstrFile, GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nil)
}
}
We could easily build a Swift version of this app which pops a system standard file open dialog. That should give us a well-known, stable(ish) UI to write tests against.