Avoid closures in syscall.NewCallback, #20.
This commit is contained in:
parent
fca9f5c3ce
commit
a806229364
4 changed files with 56 additions and 40 deletions
|
@ -316,12 +316,7 @@ func browseForFolder(opts options) (string, []string, error) {
|
|||
}
|
||||
if opts.filename != "" {
|
||||
args.LParam = strptr(opts.filename)
|
||||
args.CallbackFunc = syscall.NewCallback(func(wnd uintptr, msg uint32, lparam, data uintptr) uintptr {
|
||||
if msg == 1 { // BFFM_INITIALIZED
|
||||
sendMessage.Call(wnd, 1024+103 /* BFFM_SETSELECTIONW */, 1 /* TRUE */, data)
|
||||
}
|
||||
return 0
|
||||
})
|
||||
args.CallbackFunc = syscall.NewCallback(browseForFolderCallback)
|
||||
defer runtime.KeepAlive(opts.filename)
|
||||
}
|
||||
|
||||
|
@ -349,6 +344,13 @@ func browseForFolder(opts options) (string, []string, error) {
|
|||
return str, []string{str}, nil
|
||||
}
|
||||
|
||||
func browseForFolderCallback(wnd uintptr, msg uint32, lparam, data uintptr) uintptr {
|
||||
if msg == 1 { // BFFM_INITIALIZED
|
||||
sendMessage.Call(wnd, 1024+103 /* BFFM_SETSELECTIONW */, 1 /* TRUE */, data)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func initDirNameExt(filename string, name []uint16) (dir *uint16, ext *uint16) {
|
||||
d, n := splitDirAndName(filename)
|
||||
e := filepath.Ext(n)
|
||||
|
|
|
@ -132,3 +132,12 @@ func TestMessage_script(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessage_callbacks(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
for i := 0; i < 2000; i++ {
|
||||
zenity.Error("text", zenity.Context(ctx))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,25 +79,28 @@ func message(kind messageKind, text string, opts options) error {
|
|||
func hookMessageLabels(kind messageKind, opts options) (unhook context.CancelFunc, err error) {
|
||||
return hookDialog(opts.ctx, func(wnd uintptr) {
|
||||
enumChildWindows.Call(wnd,
|
||||
syscall.NewCallback(func(wnd, lparam uintptr) uintptr {
|
||||
var name [8]uint16
|
||||
getClassName.Call(wnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if syscall.UTF16ToString(name[:]) == "Button" {
|
||||
ctl, _, _ := getDlgCtrlID.Call(wnd)
|
||||
var text *string
|
||||
switch ctl {
|
||||
case 1, 6: // IDOK, IDYES
|
||||
text = opts.okLabel
|
||||
case 2: // IDCANCEL
|
||||
text = opts.cancelLabel
|
||||
case 7: // IDNO
|
||||
text = opts.extraButton
|
||||
}
|
||||
if text != nil {
|
||||
setWindowText.Call(wnd, strptr(*text))
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}), 0)
|
||||
syscall.NewCallback(hookMessageLabelsCallback),
|
||||
uintptr(unsafe.Pointer(&opts)))
|
||||
})
|
||||
}
|
||||
|
||||
func hookMessageLabelsCallback(wnd uintptr, lparam *options) uintptr {
|
||||
var name [8]uint16
|
||||
getClassName.Call(wnd, uintptr(unsafe.Pointer(&name)), uintptr(len(name)))
|
||||
if syscall.UTF16ToString(name[:]) == "Button" {
|
||||
ctl, _, _ := getDlgCtrlID.Call(wnd)
|
||||
var text *string
|
||||
switch ctl {
|
||||
case 1, 6: // IDOK, IDYES
|
||||
text = lparam.okLabel
|
||||
case 2: // IDCANCEL
|
||||
text = lparam.cancelLabel
|
||||
case 7: // IDNO
|
||||
text = lparam.extraButton
|
||||
}
|
||||
if text != nil {
|
||||
setWindowText.Call(wnd, strptr(*text))
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
|
|
@ -90,21 +90,13 @@ func strptr(s string) uintptr {
|
|||
}
|
||||
|
||||
func setup() context.CancelFunc {
|
||||
var hwnd uintptr
|
||||
enumWindows.Call(syscall.NewCallback(func(wnd, lparam uintptr) uintptr {
|
||||
var pid uintptr
|
||||
getWindowThreadProcessId.Call(wnd, uintptr(unsafe.Pointer(&pid)))
|
||||
if int(pid) == os.Getpid() {
|
||||
hwnd = wnd
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}), 0)
|
||||
if hwnd == 0 {
|
||||
hwnd, _, _ = getConsoleWindow.Call()
|
||||
var wnd uintptr
|
||||
enumWindows.Call(syscall.NewCallback(setupEnumCallback), uintptr(unsafe.Pointer(&wnd)))
|
||||
if wnd == 0 {
|
||||
wnd, _, _ = getConsoleWindow.Call()
|
||||
}
|
||||
if hwnd != 0 {
|
||||
setForegroundWindow.Call(hwnd)
|
||||
if wnd != 0 {
|
||||
setForegroundWindow.Call(wnd)
|
||||
}
|
||||
|
||||
runtime.LockOSThread()
|
||||
|
@ -140,6 +132,16 @@ func setup() context.CancelFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func setupEnumCallback(wnd uintptr, lparam *uintptr) uintptr {
|
||||
var pid uintptr
|
||||
getWindowThreadProcessId.Call(wnd, uintptr(unsafe.Pointer(&pid)))
|
||||
if int(pid) == os.Getpid() {
|
||||
*lparam = wnd
|
||||
return 0 // stop enumeration
|
||||
}
|
||||
return 1 // continue enumeration
|
||||
}
|
||||
|
||||
func commDlgError() error {
|
||||
s, _, _ := commDlgExtendedError.Call()
|
||||
if s == 0 {
|
||||
|
|
Loading…
Reference in a new issue