Refactor (windows).
This commit is contained in:
parent
d33a18d05a
commit
d47150a866
24 changed files with 222 additions and 145 deletions
|
@ -27,7 +27,7 @@ func selectColor(opts options) (color.Color, error) {
|
||||||
|
|
||||||
var args win.CHOOSECOLOR
|
var args win.CHOOSECOLOR
|
||||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||||
args.Owner, _ = opts.attach.(uintptr)
|
args.Owner, _ = opts.attach.(win.HWND)
|
||||||
args.CustColors = &customColors
|
args.CustColors = &customColors
|
||||||
|
|
||||||
if opts.color != nil {
|
if opts.color != nil {
|
||||||
|
|
|
@ -37,22 +37,6 @@ const (
|
||||||
_SWP_NOMOVE = 0x0002
|
_SWP_NOMOVE = 0x0002
|
||||||
_SWP_NOZORDER = 0x0004
|
_SWP_NOZORDER = 0x0004
|
||||||
|
|
||||||
_MB_OKCANCEL = 0x00000001
|
|
||||||
_MB_YESNOCANCEL = 0x00000003
|
|
||||||
_MB_YESNO = 0x00000004
|
|
||||||
_MB_ICONERROR = 0x00000010
|
|
||||||
_MB_ICONQUESTION = 0x00000020
|
|
||||||
_MB_ICONWARNING = 0x00000030
|
|
||||||
_MB_ICONINFORMATION = 0x00000040
|
|
||||||
_MB_DEFBUTTON1 = 0x00000000
|
|
||||||
_MB_DEFBUTTON2 = 0x00000100
|
|
||||||
_MB_DEFBUTTON3 = 0x00000200
|
|
||||||
|
|
||||||
_IDOK = 1
|
|
||||||
_IDCANCEL = 2
|
|
||||||
_IDYES = 6
|
|
||||||
_IDNO = 7
|
|
||||||
|
|
||||||
_SC_CLOSE = 0xf060
|
_SC_CLOSE = 0xf060
|
||||||
|
|
||||||
_WM_DESTROY = 0x0002
|
_WM_DESTROY = 0x0002
|
||||||
|
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
func calendar(text string, opts options) (time.Time, error) {
|
func calendar(text string, opts options) (time.Time, error) {
|
||||||
|
@ -56,12 +58,12 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
|
||||||
}
|
}
|
||||||
defer unregisterClass.Call(cls, instance)
|
defer unregisterClass.Call(cls, instance)
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
||||||
cls, strptr(*opts.title),
|
cls, strptr(*opts.title),
|
||||||
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
||||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||||
281, 281, owner, 0, instance, uintptr(unsafe.Pointer(dlg)))
|
281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
|
||||||
|
|
||||||
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
||||||
strptr("STATIC"), strptr(text),
|
strptr("STATIC"), strptr(text),
|
||||||
|
@ -77,16 +79,16 @@ func (dlg *calendarDialog) setup(text string, opts options) (time.Time, error) {
|
||||||
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.okLabel),
|
strptr("BUTTON"), strptr(*opts.okLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDOK, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
|
||||||
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDCANCEL, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
|
||||||
if opts.extraButton != nil {
|
if opts.extraButton != nil {
|
||||||
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.extraButton),
|
strptr("BUTTON"), strptr(*opts.extraButton),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDNO, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.time != nil {
|
if opts.time != nil {
|
||||||
|
@ -168,13 +170,13 @@ func calendarProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
|
||||||
switch wparam {
|
switch wparam {
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
var date _SYSTEMTIME
|
var date _SYSTEMTIME
|
||||||
sendMessage.Call(dlg.dateCtl, _MCM_GETCURSEL, 0, uintptr(unsafe.Pointer(&date)))
|
sendMessage.Call(dlg.dateCtl, _MCM_GETCURSEL, 0, uintptr(unsafe.Pointer(&date)))
|
||||||
dlg.out = time.Date(int(date.year), time.Month(date.month), int(date.day), 0, 0, 0, 0, time.UTC)
|
dlg.out = time.Date(int(date.year), time.Month(date.month), int(date.day), 0, 0, 0, 0, time.UTC)
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
dlg.err = ErrExtraButton
|
dlg.err = ErrExtraButton
|
||||||
}
|
}
|
||||||
destroyWindow.Call(wnd)
|
destroyWindow.Call(wnd)
|
||||||
|
|
|
@ -3,6 +3,8 @@ package zenity
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
func entry(text string, opts options) (string, error) {
|
func entry(text string, opts options) (string, error) {
|
||||||
|
@ -55,12 +57,12 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
||||||
}
|
}
|
||||||
defer unregisterClass.Call(cls, instance)
|
defer unregisterClass.Call(cls, instance)
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
||||||
cls, strptr(*opts.title),
|
cls, strptr(*opts.title),
|
||||||
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
||||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||||
281, 141, owner, 0, instance, uintptr(unsafe.Pointer(dlg)))
|
281, 141, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
|
||||||
|
|
||||||
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
||||||
strptr("STATIC"), strptr(text),
|
strptr("STATIC"), strptr(text),
|
||||||
|
@ -79,16 +81,16 @@ func (dlg *entryDialog) setup(text string, opts options) (string, error) {
|
||||||
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.okLabel),
|
strptr("BUTTON"), strptr(*opts.okLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
||||||
12, 66, 75, 24, dlg.wnd, _IDOK, instance, 0)
|
12, 66, 75, 24, dlg.wnd, win.IDOK, instance, 0)
|
||||||
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 66, 75, 24, dlg.wnd, _IDCANCEL, instance, 0)
|
12, 66, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
|
||||||
if opts.extraButton != nil {
|
if opts.extraButton != nil {
|
||||||
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.extraButton),
|
strptr("BUTTON"), strptr(*opts.extraButton),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 66, 75, 24, dlg.wnd, _IDNO, instance, 0)
|
12, 66, 75, 24, dlg.wnd, win.IDNO, instance, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.layout(getDPI(dlg.wnd))
|
dlg.layout(getDPI(dlg.wnd))
|
||||||
|
@ -162,11 +164,11 @@ func entryProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer)
|
||||||
switch wparam {
|
switch wparam {
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
dlg.out = getWindowString(dlg.editCtl)
|
dlg.out = getWindowString(dlg.editCtl)
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
dlg.err = ErrExtraButton
|
dlg.err = ErrExtraButton
|
||||||
}
|
}
|
||||||
destroyWindow.Call(wnd)
|
destroyWindow.Call(wnd)
|
||||||
|
|
|
@ -27,7 +27,7 @@ func selectFile(opts options) (string, error) {
|
||||||
|
|
||||||
var args win.OPENFILENAME
|
var args win.OPENFILENAME
|
||||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||||
args.Owner, _ = opts.attach.(uintptr)
|
args.Owner, _ = opts.attach.(win.HWND)
|
||||||
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
|
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
|
||||||
|
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
|
@ -73,7 +73,7 @@ func selectFileMultiple(opts options) ([]string, error) {
|
||||||
|
|
||||||
var args win.OPENFILENAME
|
var args win.OPENFILENAME
|
||||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||||
args.Owner, _ = opts.attach.(uintptr)
|
args.Owner, _ = opts.attach.(win.HWND)
|
||||||
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_ALLOWMULTISELECT | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
|
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_ALLOWMULTISELECT | win.OFN_FILEMUSTEXIST | win.OFN_EXPLORER
|
||||||
|
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
|
@ -144,7 +144,7 @@ func selectFileSave(opts options) (string, error) {
|
||||||
|
|
||||||
var args win.OPENFILENAME
|
var args win.OPENFILENAME
|
||||||
args.StructSize = uint32(unsafe.Sizeof(args))
|
args.StructSize = uint32(unsafe.Sizeof(args))
|
||||||
args.Owner, _ = opts.attach.(uintptr)
|
args.Owner, _ = opts.attach.(win.HWND)
|
||||||
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_PATHMUSTEXIST | win.OFN_NOREADONLYRETURN | win.OFN_EXPLORER
|
args.Flags = win.OFN_NOCHANGEDIR | win.OFN_PATHMUSTEXIST | win.OFN_NOREADONLYRETURN | win.OFN_EXPLORER
|
||||||
|
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
|
@ -252,8 +252,8 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
|
||||||
defer unhook()
|
defer unhook()
|
||||||
}
|
}
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
hr, _, _ = dialog.Call(dialog.Show, owner)
|
hr, _, _ = dialog.Call(dialog.Show, uintptr(owner))
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return "", nil, opts.ctx.Err()
|
return "", nil, opts.ctx.Err()
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ func pickFolders(opts options, multi bool) (str string, lst []string, err error)
|
||||||
|
|
||||||
func browseForFolder(opts options) (string, []string, error) {
|
func browseForFolder(opts options) (string, []string, error) {
|
||||||
var args win.BROWSEINFO
|
var args win.BROWSEINFO
|
||||||
args.Owner, _ = opts.attach.(uintptr)
|
args.Owner, _ = opts.attach.(win.HWND)
|
||||||
args.Flags = 0x1 // BIF_RETURNONLYFSDIRS
|
args.Flags = 0x1 // BIF_RETURNONLYFSDIRS
|
||||||
|
|
||||||
if opts.title != nil {
|
if opts.title != nil {
|
||||||
|
|
|
@ -17,8 +17,8 @@ const (
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-choosecolorw-r1
|
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-choosecolorw-r1
|
||||||
type CHOOSECOLOR struct {
|
type CHOOSECOLOR struct {
|
||||||
StructSize uint32
|
StructSize uint32
|
||||||
Owner uintptr
|
Owner HWND
|
||||||
Instance uintptr
|
Instance HWND
|
||||||
RgbResult uint32
|
RgbResult uint32
|
||||||
CustColors *[16]uint32
|
CustColors *[16]uint32
|
||||||
Flags uint32
|
Flags uint32
|
||||||
|
@ -42,8 +42,8 @@ const (
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew
|
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew
|
||||||
type OPENFILENAME struct {
|
type OPENFILENAME struct {
|
||||||
StructSize uint32
|
StructSize uint32
|
||||||
Owner uintptr
|
Owner HWND
|
||||||
Instance uintptr
|
Instance Handle
|
||||||
Filter *uint16
|
Filter *uint16
|
||||||
CustomFilter *uint16
|
CustomFilter *uint16
|
||||||
MaxCustomFilter uint32
|
MaxCustomFilter uint32
|
||||||
|
|
30
internal/win/gdi32.go
Normal file
30
internal/win/gdi32.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package win
|
||||||
|
|
||||||
|
const (
|
||||||
|
LOGPIXELSX = 88
|
||||||
|
LOGPIXELSY = 90
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
|
||||||
|
type LOGFONT struct {
|
||||||
|
Height int32
|
||||||
|
Width int32
|
||||||
|
Escapement int32
|
||||||
|
Orientation int32
|
||||||
|
Weight int32
|
||||||
|
Italic byte
|
||||||
|
Underline byte
|
||||||
|
StrikeOut byte
|
||||||
|
CharSet byte
|
||||||
|
OutPrecision byte
|
||||||
|
ClipPrecision byte
|
||||||
|
Quality byte
|
||||||
|
PitchAndFamily byte
|
||||||
|
FaceName [32]uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys CreateFontIndirect(lf *LOGFONT) (font Handle) = gdi32.CreateFontIndirectW
|
||||||
|
//sys DeleteObject(o Handle) (ok bool) = gdi32.DeleteObject
|
||||||
|
//sys GetDeviceCaps(dc Handle, index int) (cap uintptr) = gdi32.GetDeviceCaps
|
|
@ -1,5 +1,6 @@
|
||||||
// Package win is internal. DO NOT USE.
|
//go:build generate
|
||||||
package win
|
|
||||||
|
|
||||||
//go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go
|
//go:generate -command mkwinsyscall go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go
|
||||||
//go:generate mkwinsyscall comctl32.go comdlg32.go ole32.go shell32.go
|
//go:generate mkwinsyscall comctl32.go comdlg32.go gdi32.go ole32.go shell32.go user32.go
|
||||||
|
|
||||||
|
package win
|
|
@ -9,7 +9,7 @@ const (
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow
|
// https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/ns-shlobj_core-browseinfow
|
||||||
type BROWSEINFO struct {
|
type BROWSEINFO struct {
|
||||||
Owner uintptr
|
Owner HWND
|
||||||
Root uintptr
|
Root uintptr
|
||||||
DisplayName *uint16
|
DisplayName *uint16
|
||||||
Title *uint16
|
Title *uint16
|
||||||
|
@ -22,11 +22,11 @@ type BROWSEINFO struct {
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw
|
// https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-notifyicondataw
|
||||||
type NOTIFYICONDATA struct {
|
type NOTIFYICONDATA struct {
|
||||||
StructSize uint32
|
StructSize uint32
|
||||||
Wnd uintptr
|
Wnd HWND
|
||||||
ID uint32
|
ID uint32
|
||||||
Flags uint32
|
Flags uint32
|
||||||
CallbackMessage uint32
|
CallbackMessage uint32
|
||||||
Icon uintptr
|
Icon Handle
|
||||||
Tip [128]uint16 // NOTIFYICONDATAA_V1_SIZE
|
Tip [128]uint16 // NOTIFYICONDATAA_V1_SIZE
|
||||||
State uint32
|
State uint32
|
||||||
StateMask uint32
|
StateMask uint32
|
||||||
|
@ -34,8 +34,8 @@ type NOTIFYICONDATA struct {
|
||||||
Version uint32
|
Version uint32
|
||||||
InfoTitle [64]uint16
|
InfoTitle [64]uint16
|
||||||
InfoFlags uint32
|
InfoFlags uint32
|
||||||
// GuidItem [16]byte // NOTIFYICONDATAA_V2_SIZE
|
// GuidItem [16]byte // NOTIFYICONDATAA_V2_SIZE
|
||||||
// BalloonIcon syscall.Handle // NOTIFYICONDATAA_V3_SIZE
|
// BalloonIcon Handle // NOTIFYICONDATAA_V3_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
type IShellItem struct {
|
type IShellItem struct {
|
||||||
|
|
34
internal/win/user32.go
Normal file
34
internal/win/user32.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package win
|
||||||
|
|
||||||
|
import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
|
const (
|
||||||
|
IDOK = 1
|
||||||
|
IDCANCEL = 2
|
||||||
|
IDABORT = 3
|
||||||
|
IDRETRY = 4
|
||||||
|
IDIGNORE = 5
|
||||||
|
IDYES = 6
|
||||||
|
IDNO = 7
|
||||||
|
|
||||||
|
MB_OK = windows.MB_OK
|
||||||
|
MB_OKCANCEL = windows.MB_OKCANCEL
|
||||||
|
MB_ABORTRETRYIGNORE = windows.MB_ABORTRETRYIGNORE
|
||||||
|
MB_YESNOCANCEL = windows.MB_YESNOCANCEL
|
||||||
|
MB_YESNO = windows.MB_YESNO
|
||||||
|
MB_RETRYCANCEL = windows.MB_RETRYCANCEL
|
||||||
|
MB_CANCELTRYCONTINUE = windows.MB_CANCELTRYCONTINUE
|
||||||
|
MB_ICONERROR = windows.MB_ICONERROR
|
||||||
|
MB_ICONQUESTION = windows.MB_ICONQUESTION
|
||||||
|
MB_ICONWARNING = windows.MB_ICONWARNING
|
||||||
|
MB_ICONINFORMATION = windows.MB_ICONINFORMATION
|
||||||
|
MB_DEFBUTTON1 = windows.MB_DEFBUTTON1
|
||||||
|
MB_DEFBUTTON2 = windows.MB_DEFBUTTON2
|
||||||
|
MB_DEFBUTTON3 = windows.MB_DEFBUTTON3
|
||||||
|
)
|
||||||
|
|
||||||
|
func MessageBox(hwnd HWND, text *uint16, caption *uint16, boxtype uint32) (ret int32, err error) {
|
||||||
|
return windows.MessageBox(hwnd, text, caption, boxtype)
|
||||||
|
}
|
9
internal/win/win32.go
Normal file
9
internal/win/win32.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
//go:build windows
|
||||||
|
|
||||||
|
// Package win is internal. DO NOT USE.
|
||||||
|
package win
|
||||||
|
|
||||||
|
import "golang.org/x/sys/windows"
|
||||||
|
|
||||||
|
type Handle = windows.Handle
|
||||||
|
type HWND = windows.HWND
|
|
@ -40,6 +40,7 @@ func errnoErr(e syscall.Errno) error {
|
||||||
var (
|
var (
|
||||||
modcomctl32 = windows.NewLazySystemDLL("comctl32.dll")
|
modcomctl32 = windows.NewLazySystemDLL("comctl32.dll")
|
||||||
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
modcomdlg32 = windows.NewLazySystemDLL("comdlg32.dll")
|
||||||
|
modgdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
||||||
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||||
modshell32 = windows.NewLazySystemDLL("shell32.dll")
|
modshell32 = windows.NewLazySystemDLL("shell32.dll")
|
||||||
|
|
||||||
|
@ -48,6 +49,9 @@ var (
|
||||||
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
|
procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
|
||||||
procGetOpenFileNameW = modcomdlg32.NewProc("GetOpenFileNameW")
|
procGetOpenFileNameW = modcomdlg32.NewProc("GetOpenFileNameW")
|
||||||
procGetSaveFileNameW = modcomdlg32.NewProc("GetSaveFileNameW")
|
procGetSaveFileNameW = modcomdlg32.NewProc("GetSaveFileNameW")
|
||||||
|
procCreateFontIndirectW = modgdi32.NewProc("CreateFontIndirectW")
|
||||||
|
procDeleteObject = modgdi32.NewProc("DeleteObject")
|
||||||
|
procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps")
|
||||||
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
|
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
|
||||||
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
|
||||||
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
|
procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolder")
|
||||||
|
@ -86,6 +90,24 @@ func GetSaveFileName(ofn *OPENFILENAME) (ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateFontIndirect(lf *LOGFONT) (font Handle) {
|
||||||
|
r0, _, _ := syscall.Syscall(procCreateFontIndirectW.Addr(), 1, uintptr(unsafe.Pointer(lf)), 0, 0)
|
||||||
|
font = Handle(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteObject(o Handle) (ok bool) {
|
||||||
|
r0, _, _ := syscall.Syscall(procDeleteObject.Addr(), 1, uintptr(o), 0, 0)
|
||||||
|
ok = r0 != 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetDeviceCaps(dc Handle, index int) (cap uintptr) {
|
||||||
|
r0, _, _ := syscall.Syscall(procGetDeviceCaps.Addr(), 2, uintptr(dc), uintptr(index), 0)
|
||||||
|
cap = uintptr(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) {
|
func CoCreateInstance(clsid uintptr, unkOuter unsafe.Pointer, clsContext int32, iid uintptr, address unsafe.Pointer) (ret error) {
|
||||||
r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0)
|
r0, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, uintptr(clsid), uintptr(unkOuter), uintptr(clsContext), uintptr(iid), uintptr(address), 0)
|
||||||
if r0 != 0 {
|
if r0 != 0 {
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
package zenutil
|
|
||||||
|
|
||||||
//go:generate go run osa_generator.go osascripts/
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Code generated by zenity; DO NOT EDIT.
|
// Code generated by zenity; DO NOT EDIT.
|
||||||
|
|
||||||
//go:build darwin
|
//go:build darwin
|
||||||
|
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//go:build tools
|
//go:build generate
|
||||||
|
|
||||||
|
//go:generate go run osa_generator.go osascripts/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ func minify(data []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var generator = template.Must(template.New("").Parse(`// Code generated by zenity; DO NOT EDIT.
|
var generator = template.Must(template.New("").Parse(`// Code generated by zenity; DO NOT EDIT.
|
||||||
|
|
||||||
//go:build darwin
|
//go:build darwin
|
||||||
|
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
||||||
import "strconv"
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
// ParseWindowId is internal.
|
// ParseWindowId is internal.
|
||||||
func ParseWindowId(id string) uintptr {
|
func ParseWindowId(id string) windows.HWND {
|
||||||
hwnd, _ := strconv.ParseUint(id, 0, 64)
|
hwnd, _ := strconv.ParseUint(id, 0, 64)
|
||||||
return uintptr(hwnd)
|
return windows.HWND(uintptr(hwnd))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParentWindowId is internal.
|
// GetParentWindowId is internal.
|
||||||
|
|
|
@ -3,6 +3,8 @@ package zenity
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
func list(text string, items []string, opts options) (string, error) {
|
func list(text string, items []string, opts options) (string, error) {
|
||||||
|
@ -72,12 +74,12 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
||||||
}
|
}
|
||||||
defer unregisterClass.Call(cls, instance)
|
defer unregisterClass.Call(cls, instance)
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
||||||
cls, strptr(*opts.title),
|
cls, strptr(*opts.title),
|
||||||
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
||||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||||
281, 281, owner, 0, instance, uintptr(unsafe.Pointer(dlg)))
|
281, 281, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
|
||||||
|
|
||||||
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
||||||
strptr("STATIC"), strptr(text),
|
strptr("STATIC"), strptr(text),
|
||||||
|
@ -96,16 +98,16 @@ func (dlg *listDialog) setup(text string, opts options) ([]string, error) {
|
||||||
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.okLabel),
|
strptr("BUTTON"), strptr(*opts.okLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDOK, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDOK, instance, 0)
|
||||||
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDCANCEL, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
|
||||||
if opts.extraButton != nil {
|
if opts.extraButton != nil {
|
||||||
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.extraButton),
|
strptr("BUTTON"), strptr(*opts.extraButton),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 206, 75, 24, dlg.wnd, _IDNO, instance, 0)
|
12, 206, 75, 24, dlg.wnd, win.IDNO, instance, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, item := range dlg.items {
|
for _, item := range dlg.items {
|
||||||
|
@ -182,7 +184,7 @@ func listProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer) u
|
||||||
switch wparam {
|
switch wparam {
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
if dlg.multiple {
|
if dlg.multiple {
|
||||||
if len, _, _ := sendMessage.Call(dlg.listCtl, _LB_GETSELCOUNT, 0, 0); int32(len) >= 0 {
|
if len, _, _ := sendMessage.Call(dlg.listCtl, _LB_GETSELCOUNT, 0, 0); int32(len) >= 0 {
|
||||||
dlg.out = make([]string, len)
|
dlg.out = make([]string, len)
|
||||||
|
@ -201,9 +203,9 @@ func listProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointer) u
|
||||||
dlg.out = []string{}
|
dlg.out = []string{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
dlg.err = ErrExtraButton
|
dlg.err = ErrExtraButton
|
||||||
}
|
}
|
||||||
destroyWindow.Call(wnd)
|
destroyWindow.Call(wnd)
|
||||||
|
|
|
@ -4,54 +4,55 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
getDlgCtrlID = user32.NewProc("GetDlgCtrlID")
|
getDlgCtrlID = user32.NewProc("GetDlgCtrlID")
|
||||||
messageBox = user32.NewProc("MessageBoxW")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func message(kind messageKind, text string, opts options) error {
|
func message(kind messageKind, text string, opts options) error {
|
||||||
var flags uintptr
|
var flags uint32
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case kind == questionKind && opts.extraButton != nil:
|
case kind == questionKind && opts.extraButton != nil:
|
||||||
flags |= _MB_YESNOCANCEL
|
flags |= win.MB_YESNOCANCEL
|
||||||
case kind == questionKind:
|
case kind == questionKind:
|
||||||
flags |= _MB_OKCANCEL
|
flags |= win.MB_OKCANCEL
|
||||||
case opts.extraButton != nil:
|
case opts.extraButton != nil:
|
||||||
flags |= _MB_YESNO
|
flags |= win.MB_YESNO
|
||||||
}
|
}
|
||||||
|
|
||||||
switch opts.icon {
|
switch opts.icon {
|
||||||
case ErrorIcon:
|
case ErrorIcon:
|
||||||
flags |= _MB_ICONERROR
|
flags |= win.MB_ICONERROR
|
||||||
case QuestionIcon:
|
case QuestionIcon:
|
||||||
flags |= _MB_ICONQUESTION
|
flags |= win.MB_ICONQUESTION
|
||||||
case WarningIcon:
|
case WarningIcon:
|
||||||
flags |= _MB_ICONWARNING
|
flags |= win.MB_ICONWARNING
|
||||||
case InfoIcon:
|
case InfoIcon:
|
||||||
flags |= _MB_ICONINFORMATION
|
flags |= win.MB_ICONINFORMATION
|
||||||
case NoIcon:
|
case NoIcon:
|
||||||
//
|
//
|
||||||
default:
|
default:
|
||||||
switch kind {
|
switch kind {
|
||||||
case errorKind:
|
case errorKind:
|
||||||
flags |= _MB_ICONERROR
|
flags |= win.MB_ICONERROR
|
||||||
case questionKind:
|
case questionKind:
|
||||||
flags |= _MB_ICONQUESTION
|
flags |= win.MB_ICONQUESTION
|
||||||
case warningKind:
|
case warningKind:
|
||||||
flags |= _MB_ICONWARNING
|
flags |= win.MB_ICONWARNING
|
||||||
case infoKind:
|
case infoKind:
|
||||||
flags |= _MB_ICONINFORMATION
|
flags |= win.MB_ICONINFORMATION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if kind == questionKind && opts.defaultCancel {
|
if kind == questionKind && opts.defaultCancel {
|
||||||
if opts.extraButton == nil {
|
if opts.extraButton == nil {
|
||||||
flags |= _MB_DEFBUTTON2
|
flags |= win.MB_DEFBUTTON2
|
||||||
} else {
|
} else {
|
||||||
flags |= _MB_DEFBUTTON3
|
flags |= win.MB_DEFBUTTON3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,18 +71,18 @@ func message(kind messageKind, text string, opts options) error {
|
||||||
title = syscall.StringToUTF16Ptr(*opts.title)
|
title = syscall.StringToUTF16Ptr(*opts.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
s, _, err := messageBox.Call(owner, strptr(text), uintptr(unsafe.Pointer(title)), flags)
|
s, err := win.MessageBox(owner, syscall.StringToUTF16Ptr(text), title, flags)
|
||||||
|
|
||||||
if opts.ctx != nil && opts.ctx.Err() != nil {
|
if opts.ctx != nil && opts.ctx.Err() != nil {
|
||||||
return opts.ctx.Err()
|
return opts.ctx.Err()
|
||||||
}
|
}
|
||||||
switch s {
|
switch s {
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
return nil
|
return nil
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
return ErrCanceled
|
return ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
return ErrExtraButton
|
return ErrExtraButton
|
||||||
default:
|
default:
|
||||||
return err
|
return err
|
||||||
|
@ -101,11 +102,11 @@ func hookMessageDialogCallback(wnd uintptr, lparam *options) uintptr {
|
||||||
|
|
||||||
var text *string
|
var text *string
|
||||||
switch ctl {
|
switch ctl {
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
text = lparam.okLabel
|
text = lparam.okLabel
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
text = lparam.cancelLabel
|
text = lparam.cancelLabel
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
text = lparam.extraButton
|
text = lparam.extraButton
|
||||||
}
|
}
|
||||||
if text != nil {
|
if text != nil {
|
||||||
|
|
|
@ -46,7 +46,7 @@ func notify(text string, opts options) error {
|
||||||
icon := getIcon(opts.icon)
|
icon := getIcon(opts.icon)
|
||||||
if icon.handle != 0 {
|
if icon.handle != 0 {
|
||||||
defer icon.delete()
|
defer icon.delete()
|
||||||
args.Icon = icon.handle
|
args.Icon = win.Handle(icon.handle)
|
||||||
args.Flags |= 0x00000002 // NIF_ICON
|
args.Flags |= 0x00000002 // NIF_ICON
|
||||||
args.InfoFlags |= 0x4 // NIIF_USER
|
args.InfoFlags |= 0x4 // NIIF_USER
|
||||||
}
|
}
|
||||||
|
@ -90,13 +90,13 @@ func wtsMessage(text string, opts options) error {
|
||||||
|
|
||||||
switch opts.icon {
|
switch opts.icon {
|
||||||
case ErrorIcon:
|
case ErrorIcon:
|
||||||
flags |= _MB_ICONERROR
|
flags |= win.MB_ICONERROR
|
||||||
case QuestionIcon:
|
case QuestionIcon:
|
||||||
flags |= _MB_ICONQUESTION
|
flags |= win.MB_ICONQUESTION
|
||||||
case WarningIcon:
|
case WarningIcon:
|
||||||
flags |= _MB_ICONWARNING
|
flags |= win.MB_ICONWARNING
|
||||||
case InfoIcon:
|
case InfoIcon:
|
||||||
flags |= _MB_ICONINFORMATION
|
flags |= win.MB_ICONINFORMATION
|
||||||
}
|
}
|
||||||
|
|
||||||
title := opts.title
|
title := opts.title
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
func progress(opts options) (ProgressDialog, error) {
|
func progress(opts options) (ProgressDialog, error) {
|
||||||
|
@ -135,12 +137,12 @@ func (dlg *progressDialog) setup(opts options) error {
|
||||||
}
|
}
|
||||||
defer unregisterClass.Call(cls, instance)
|
defer unregisterClass.Call(cls, instance)
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
||||||
cls, strptr(*opts.title),
|
cls, strptr(*opts.title),
|
||||||
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
||||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||||
281, 133, owner, 0, instance, uintptr(unsafe.Pointer(dlg)))
|
281, 133, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
|
||||||
|
|
||||||
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
dlg.textCtl, _, _ = createWindowEx.Call(0,
|
||||||
strptr("STATIC"), 0,
|
strptr("STATIC"), 0,
|
||||||
|
@ -159,18 +161,18 @@ func (dlg *progressDialog) setup(opts options) error {
|
||||||
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.okLabel),
|
strptr("BUTTON"), strptr(*opts.okLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON|_WS_DISABLED,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON|_WS_DISABLED,
|
||||||
12, 58, 75, 24, dlg.wnd, _IDOK, instance, 0)
|
12, 58, 75, 24, dlg.wnd, win.IDOK, instance, 0)
|
||||||
if !opts.noCancel {
|
if !opts.noCancel {
|
||||||
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 58, 75, 24, dlg.wnd, _IDCANCEL, instance, 0)
|
12, 58, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
|
||||||
}
|
}
|
||||||
if opts.extraButton != nil {
|
if opts.extraButton != nil {
|
||||||
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.extraButton),
|
strptr("BUTTON"), strptr(*opts.extraButton),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 58, 75, 24, dlg.wnd, _IDNO, instance, 0)
|
12, 58, 75, 24, dlg.wnd, win.IDNO, instance, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.layout(getDPI(dlg.wnd))
|
dlg.layout(getDPI(dlg.wnd))
|
||||||
|
@ -256,11 +258,11 @@ func progressProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
|
||||||
switch wparam {
|
switch wparam {
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
//
|
//
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
dlg.err = ErrExtraButton
|
dlg.err = ErrExtraButton
|
||||||
}
|
}
|
||||||
destroyWindow.Call(wnd)
|
destroyWindow.Call(wnd)
|
||||||
|
|
|
@ -3,6 +3,8 @@ package zenity
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/ncruces/zenity/internal/win"
|
||||||
)
|
)
|
||||||
|
|
||||||
func password(opts options) (string, string, error) {
|
func password(opts options) (string, string, error) {
|
||||||
|
@ -65,12 +67,12 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
||||||
}
|
}
|
||||||
defer unregisterClass.Call(cls, instance)
|
defer unregisterClass.Call(cls, instance)
|
||||||
|
|
||||||
owner, _ := opts.attach.(uintptr)
|
owner, _ := opts.attach.(win.HWND)
|
||||||
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
dlg.wnd, _, _ = createWindowEx.Call(_WS_EX_CONTROLPARENT|_WS_EX_WINDOWEDGE|_WS_EX_DLGMODALFRAME,
|
||||||
cls, strptr(*opts.title),
|
cls, strptr(*opts.title),
|
||||||
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
_WS_POPUPWINDOW|_WS_CLIPSIBLINGS|_WS_DLGFRAME,
|
||||||
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
_CW_USEDEFAULT, _CW_USEDEFAULT,
|
||||||
281, 191, owner, 0, instance, uintptr(unsafe.Pointer(dlg)))
|
281, 191, uintptr(owner), 0, instance, uintptr(unsafe.Pointer(dlg)))
|
||||||
|
|
||||||
dlg.uTextCtl, _, _ = createWindowEx.Call(0,
|
dlg.uTextCtl, _, _ = createWindowEx.Call(0,
|
||||||
strptr("STATIC"), strptr("Username:"),
|
strptr("STATIC"), strptr("Username:"),
|
||||||
|
@ -96,16 +98,16 @@ func (dlg *passwordDialog) setup(opts options) (string, string, error) {
|
||||||
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
dlg.okBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.okLabel),
|
strptr("BUTTON"), strptr(*opts.okLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP|_BS_DEFPUSHBUTTON,
|
||||||
12, 116, 75, 24, dlg.wnd, _IDOK, instance, 0)
|
12, 116, 75, 24, dlg.wnd, win.IDOK, instance, 0)
|
||||||
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
dlg.cancelBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
strptr("BUTTON"), strptr(*opts.cancelLabel),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 116, 75, 24, dlg.wnd, _IDCANCEL, instance, 0)
|
12, 116, 75, 24, dlg.wnd, win.IDCANCEL, instance, 0)
|
||||||
if opts.extraButton != nil {
|
if opts.extraButton != nil {
|
||||||
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
dlg.extraBtn, _, _ = createWindowEx.Call(0,
|
||||||
strptr("BUTTON"), strptr(*opts.extraButton),
|
strptr("BUTTON"), strptr(*opts.extraButton),
|
||||||
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
_WS_CHILD|_WS_VISIBLE|_WS_GROUP|_WS_TABSTOP,
|
||||||
12, 116, 75, 24, dlg.wnd, _IDNO, instance, 0)
|
12, 116, 75, 24, dlg.wnd, win.IDNO, instance, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.layout(getDPI(dlg.wnd))
|
dlg.layout(getDPI(dlg.wnd))
|
||||||
|
@ -183,12 +185,12 @@ func passwordProc(wnd uintptr, msg uint32, wparam uintptr, lparam *unsafe.Pointe
|
||||||
switch wparam {
|
switch wparam {
|
||||||
default:
|
default:
|
||||||
return 1
|
return 1
|
||||||
case _IDOK, _IDYES:
|
case win.IDOK, win.IDYES:
|
||||||
dlg.usr = getWindowString(dlg.uEditCtl)
|
dlg.usr = getWindowString(dlg.uEditCtl)
|
||||||
dlg.pwd = getWindowString(dlg.pEditCtl)
|
dlg.pwd = getWindowString(dlg.pEditCtl)
|
||||||
case _IDCANCEL:
|
case win.IDCANCEL:
|
||||||
dlg.err = ErrCanceled
|
dlg.err = ErrCanceled
|
||||||
case _IDNO:
|
case win.IDNO:
|
||||||
dlg.err = ErrExtraButton
|
dlg.err = ErrExtraButton
|
||||||
}
|
}
|
||||||
destroyWindow.Call(wnd)
|
destroyWindow.Call(wnd)
|
||||||
|
|
|
@ -98,6 +98,8 @@ func pwdResult(sep string, opts options, out []byte, err error) (string, string,
|
||||||
return "", str, err
|
return "", str, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hwnd(i uint64) uintptr { return uintptr(i) }
|
||||||
|
|
||||||
// Replace with strings.Cut after 1.18.
|
// Replace with strings.Cut after 1.18.
|
||||||
func cut(s, sep string) (before, after string, found bool) {
|
func cut(s, sep string) (before, after string, found bool) {
|
||||||
if i := strings.Index(s, sep); i >= 0 {
|
if i := strings.Index(s, sep); i >= 0 {
|
||||||
|
|
|
@ -17,16 +17,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
gdi32 = windows.NewLazySystemDLL("gdi32.dll")
|
|
||||||
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
kernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
ntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
user32 = windows.NewLazySystemDLL("user32.dll")
|
user32 = windows.NewLazySystemDLL("user32.dll")
|
||||||
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
wtsapi32 = windows.NewLazySystemDLL("wtsapi32.dll")
|
||||||
|
|
||||||
createFontIndirect = gdi32.NewProc("CreateFontIndirectW")
|
|
||||||
deleteObject = gdi32.NewProc("DeleteObject")
|
|
||||||
getDeviceCaps = gdi32.NewProc("GetDeviceCaps")
|
|
||||||
|
|
||||||
activateActCtx = kernel32.NewProc("ActivateActCtx")
|
activateActCtx = kernel32.NewProc("ActivateActCtx")
|
||||||
createActCtx = kernel32.NewProc("CreateActCtxW")
|
createActCtx = kernel32.NewProc("CreateActCtxW")
|
||||||
deactivateActCtx = kernel32.NewProc("DeactivateActCtx")
|
deactivateActCtx = kernel32.NewProc("DeactivateActCtx")
|
||||||
|
@ -82,6 +77,8 @@ func strptr(s string) uintptr {
|
||||||
return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
|
return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(s)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hwnd(i uint64) win.HWND { return win.HWND(uintptr(i)) }
|
||||||
|
|
||||||
func setup() context.CancelFunc {
|
func setup() context.CancelFunc {
|
||||||
var wnd uintptr
|
var wnd uintptr
|
||||||
enumWindows.Call(syscall.NewCallback(setupEnumCallback), uintptr(unsafe.Pointer(&wnd)))
|
enumWindows.Call(syscall.NewCallback(setupEnumCallback), uintptr(unsafe.Pointer(&wnd)))
|
||||||
|
@ -264,7 +261,7 @@ func getDPI(wnd uintptr) dpi {
|
||||||
if wnd != 0 && getDpiForWindow.Find() == nil {
|
if wnd != 0 && getDpiForWindow.Find() == nil {
|
||||||
res, _, _ = getDpiForWindow.Call(wnd)
|
res, _, _ = getDpiForWindow.Call(wnd)
|
||||||
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
|
} else if dc, _, _ := getWindowDC.Call(wnd); dc != 0 {
|
||||||
res, _, _ = getDeviceCaps.Call(dc, 90) // LOGPIXELSY
|
res = win.GetDeviceCaps(win.Handle(dc), win.LOGPIXELSY)
|
||||||
releaseDC.Call(0, dc)
|
releaseDC.Call(0, dc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,8 +279,8 @@ func (d dpi) scale(dim uintptr) uintptr {
|
||||||
}
|
}
|
||||||
|
|
||||||
type font struct {
|
type font struct {
|
||||||
handle uintptr
|
handle win.Handle
|
||||||
logical _LOGFONT
|
logical win.LOGFONT
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFont() font {
|
func getFont() font {
|
||||||
|
@ -298,14 +295,14 @@ func (f *font) forDPI(dpi dpi) uintptr {
|
||||||
if h := -int32(dpi.scale(12)); f.handle == 0 || f.logical.Height != h {
|
if h := -int32(dpi.scale(12)); f.handle == 0 || f.logical.Height != h {
|
||||||
f.delete()
|
f.delete()
|
||||||
f.logical.Height = h
|
f.logical.Height = h
|
||||||
f.handle, _, _ = createFontIndirect.Call(uintptr(unsafe.Pointer(&f.logical)))
|
f.handle = win.CreateFontIndirect(&f.logical)
|
||||||
}
|
}
|
||||||
return f.handle
|
return uintptr(f.handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *font) delete() {
|
func (f *font) delete() {
|
||||||
if f.handle != 0 {
|
if f.handle != 0 {
|
||||||
deleteObject.Call(f.handle)
|
win.DeleteObject(f.handle)
|
||||||
f.handle = 0
|
f.handle = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -470,24 +467,6 @@ type _CWPRETSTRUCT struct {
|
||||||
Wnd uintptr
|
Wnd uintptr
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-logfontw
|
|
||||||
type _LOGFONT struct {
|
|
||||||
Height int32
|
|
||||||
Width int32
|
|
||||||
Escapement int32
|
|
||||||
Orientation int32
|
|
||||||
Weight int32
|
|
||||||
Italic byte
|
|
||||||
Underline byte
|
|
||||||
StrikeOut byte
|
|
||||||
CharSet byte
|
|
||||||
OutPrecision byte
|
|
||||||
ClipPrecision byte
|
|
||||||
Quality byte
|
|
||||||
PitchAndFamily byte
|
|
||||||
FaceName [32]uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsw
|
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-nonclientmetricsw
|
||||||
type _NONCLIENTMETRICS struct {
|
type _NONCLIENTMETRICS struct {
|
||||||
Size uint32
|
Size uint32
|
||||||
|
@ -496,15 +475,15 @@ type _NONCLIENTMETRICS struct {
|
||||||
ScrollHeight int32
|
ScrollHeight int32
|
||||||
CaptionWidth int32
|
CaptionWidth int32
|
||||||
CaptionHeight int32
|
CaptionHeight int32
|
||||||
CaptionFont _LOGFONT
|
CaptionFont win.LOGFONT
|
||||||
SmCaptionWidth int32
|
SmCaptionWidth int32
|
||||||
SmCaptionHeight int32
|
SmCaptionHeight int32
|
||||||
SmCaptionFont _LOGFONT
|
SmCaptionFont win.LOGFONT
|
||||||
MenuWidth int32
|
MenuWidth int32
|
||||||
MenuHeight int32
|
MenuHeight int32
|
||||||
MenuFont _LOGFONT
|
MenuFont win.LOGFONT
|
||||||
StatusFont _LOGFONT
|
StatusFont win.LOGFONT
|
||||||
MessageFont _LOGFONT
|
MessageFont win.LOGFONT
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg
|
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg
|
||||||
|
|
|
@ -201,7 +201,7 @@ func Attach(id any) Option {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "windows":
|
case "windows":
|
||||||
if v := reflect.ValueOf(id); v.Kind() == reflect.Uintptr {
|
if v := reflect.ValueOf(id); v.Kind() == reflect.Uintptr {
|
||||||
id = uintptr(v.Uint())
|
id = hwnd(v.Uint())
|
||||||
} else {
|
} else {
|
||||||
panic("interface conversion: expected uintptr")
|
panic("interface conversion: expected uintptr")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue