Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build an app to write tests against #110

Open
tristanlabelle opened this issue Oct 20, 2023 · 4 comments
Open

Build an app to write tests against #110

tristanlabelle opened this issue Oct 20, 2023 · 4 comments

Comments

@tristanlabelle
Copy link
Contributor

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.

int main() {
	OPENFILENAMEW openFileName = {};
	openFileName.lStructSize = sizeof(OPENFILENAMEW);
	wchar_t filePath[256] = {};
	filePath[0] = 0;
	openFileName.lpstrFile = filePath;
	openFileName.nMaxFile = 256;
	GetOpenFileNameW(&openFileName);
}
@Squidonomics
Copy link
Contributor

Squidonomics commented Dec 3, 2023

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)")
    }
}

@tristanlabelle
Copy link
Contributor Author

@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.

@Squidonomics
Copy link
Contributor

@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.")
    }
}

@compnerd
Copy link
Collaborator

compnerd commented Dec 4, 2023

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)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants