Files
gopad/file_dialogs_windows.go
2024-04-20 14:50:17 +04:00

72 lines
1.6 KiB
Go
Executable File

package main
import (
"fmt"
"syscall"
"unicode/utf16"
"unsafe"
)
var (
comdlg32 = syscall.NewLazyDLL("Comdlg32.dll")
procGetOpenFileName = comdlg32.NewProc("GetOpenFileNameW")
)
var (
Err_No_File_Chosen = fmt.Errorf("no file was chosen")
)
func OpenFileDialog(title string) (filepath string, err error) {
type OPENFILENAMEW struct {
LStructSize uint32
HwndOwner syscall.Handle
HInstance syscall.Handle
Filter *uint16
CustomFilter *uint16
MaxCustFilter uint32
FilterIndex uint32
File *uint16
MaxFile uint32
FileTitle *uint16
MaxFileTitle uint32
InitialDir *uint16
Title *uint16
Flags uint32
FileOffset uint16
FileExtension uint16
DefExt *uint16
CustData uintptr
FnHook syscall.Handle
TemplateName *uint16
PvReserved uintptr
DwReserved uint32
FlagsEx uint32
}
titleByteArr := utf16.Encode([]rune(title + "\x00"))
filterByteArr := utf16.Encode([]rune("All Files (*.*)\x00*.*\x00Text Files (*.txt)\x00*.txt\x00\x00"))
filenameByteArr := make([]uint16, syscall.MAX_LONG_PATH)
ofn := &OPENFILENAMEW{
HwndOwner: 0,
HInstance: 0,
LStructSize: uint32(unsafe.Sizeof(OPENFILENAMEW{})),
Title: &titleByteArr[0],
Filter: &filterByteArr[0],
File: &filenameByteArr[0],
MaxFile: syscall.MAX_LONG_PATH,
// OFN_FILEMUSTEXIST
Flags: 0x00001000,
}
ret, _, _ := procGetOpenFileName.Call(uintptr(unsafe.Pointer(ofn)))
if ret == 0 {
return "", Err_No_File_Chosen
}
filepath = syscall.UTF16ToString(filenameByteArr)
return filepath, nil
}