120 lines
2.9 KiB
Go
120 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"unicode/utf16"
|
|
"unsafe"
|
|
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
var (
|
|
comdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
|
procGetOpenFileNameW = comdlg32.NewProc("GetOpenFileNameW")
|
|
procChooseColorW = comdlg32.NewProc("ChooseColorW")
|
|
)
|
|
|
|
func slicePtr(s interface{}) uintptr {
|
|
switch v := s.(type) {
|
|
case []uint16:
|
|
if len(v) == 0 { return 0 }
|
|
return uintptr(unsafe.Pointer(&v[0]))
|
|
case []uint32:
|
|
if len(v) == 0 { return 0 }
|
|
return uintptr(unsafe.Pointer(&v[0]))
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func openFileDialog(owner uintptr) string {
|
|
type openFileName struct {
|
|
lStructSize uint32
|
|
hwndOwner uintptr
|
|
hInstance uintptr
|
|
lpstrFilter uintptr
|
|
lpstrCustomFilter uintptr
|
|
nMaxCustFilter uint32
|
|
nFilterIndex uint32
|
|
lpstrFile uintptr
|
|
nMaxFile uint32
|
|
lpstrFileTitle uintptr
|
|
nMaxFileTitle uint32
|
|
lpstrInitialDir uintptr
|
|
lpstrTitle uintptr
|
|
Flags uint32
|
|
nFileOffset uint16
|
|
nFileExtension uint16
|
|
lpstrDefExt uintptr
|
|
lCustData uintptr
|
|
lpfnHook uintptr
|
|
lpTemplateName uintptr
|
|
pvReserved uintptr
|
|
dwReserved uint32
|
|
FlagsEx uint32
|
|
}
|
|
|
|
// Filter: "Images\0*.jpg;*.png\0All\0*.*\0\0"
|
|
filterStr := "图片文件\x00*.jpg;*.jpeg;*.png;*.bmp;*.webp;*.gif\x00所有文件\x00*.*\x00\x00"
|
|
filterUTF16 := utf16.Encode([]rune(filterStr))
|
|
|
|
titleUTF16 := utf16.Encode([]rune("选择壁纸图片"))
|
|
fileBuf := make([]uint16, 260)
|
|
|
|
ofn := openFileName{
|
|
lStructSize: uint32(unsafe.Sizeof(openFileName{})),
|
|
hwndOwner: owner,
|
|
lpstrFilter: slicePtr(filterUTF16),
|
|
lpstrFile: slicePtr(fileBuf),
|
|
nMaxFile: 260,
|
|
lpstrTitle: slicePtr(titleUTF16),
|
|
Flags: 0x00001000 | 0x00000800 | 0x00000004,
|
|
}
|
|
|
|
ret, _, _ := procGetOpenFileNameW.Call(uintptr(unsafe.Pointer(&ofn)))
|
|
if ret == 0 {
|
|
return ""
|
|
}
|
|
return windows.UTF16ToString(fileBuf)
|
|
}
|
|
|
|
func colorPickerDialog(owner uintptr, initialColor string) string {
|
|
type chooseColor struct {
|
|
lStructSize uint32
|
|
hwndOwner uintptr
|
|
hInstance uintptr
|
|
rgbResult uint32
|
|
lpCustColors uintptr
|
|
Flags uint32
|
|
lCustData uintptr
|
|
lpfnHook uintptr
|
|
lpTemplateName uintptr
|
|
}
|
|
|
|
custColors := make([]uint32, 16)
|
|
|
|
var initRGB uint32
|
|
if len(initialColor) > 4 && initialColor[0] == '#' {
|
|
var r, g, b uint32
|
|
fmt.Sscanf(initialColor[1:], "%02x%02x%02x", &r, &g, &b)
|
|
initRGB = r | (g << 8) | (b << 16)
|
|
}
|
|
|
|
cc := chooseColor{
|
|
lStructSize: uint32(unsafe.Sizeof(chooseColor{})),
|
|
hwndOwner: owner,
|
|
rgbResult: initRGB,
|
|
lpCustColors: slicePtr(custColors),
|
|
Flags: 0x00000002,
|
|
}
|
|
|
|
ret, _, _ := procChooseColorW.Call(uintptr(unsafe.Pointer(&cc)))
|
|
if ret == 0 {
|
|
return ""
|
|
}
|
|
|
|
r := cc.rgbResult & 0xFF
|
|
g := (cc.rgbResult >> 8) & 0xFF
|
|
b := (cc.rgbResult >> 16) & 0xFF
|
|
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
|
|
}
|