goにてクロスプラットフォームで動作するアプリを作成するのに試したことを備忘録として残す。
各環境(MacとWindows)でメッセージボックスを表示することを(今更)試した。
環境
・Go(1.16.3)
・Mojave10.14.6(開発環境)
・Windows10
ソースコード
ディレクトリ構成
.
├── util
│ ├── messagebox_darwin.go
│ └── messagebox_windows.go
└── main.go
ソースは下記のようになる。
main.go
package main
import (
util "crossMsg/util"
)
func main() {
util.MessageBox("title", "test")
}
messagebox_darwin.go
package util
import (
"fmt"
"os/exec"
"strings"
"syscall"
)
func MessageBox(title, text string) bool {
script := `set T to button returned of ` +
`(display dialog "%s" with title "%s" buttons {"No", "Yes"} default button "Yes")`
out, err := exec.Command("osascript", "-e", fmt.Sprintf(script, text, title)).Output()
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
return exitError.Sys().(syscall.WaitStatus).ExitStatus() == 0
}
}
return strings.TrimSpace(string(out)) == "Yes"
}
messagebox_windows.go
package util
import (
"syscall"
"unsafe"
)
func MessageBox(title, text string) bool {
user32 := syscall.NewLazyDLL("user32.dll")
messageBoxW := user32.NewProc("MessageBoxW")
mbYesNo := 0x00000004
mbIconQuestion := 0x00000020
idYes := 6
ret, _, _ := messageBoxW.Call(0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))), uintptr(uint(mbYesNo|mbIconQuestion)))
return int(ret) == idYes
}
ビルド
macはそのまま
go build .
windowsも特に変えることなく、
GOOS=windows GOARCH=386 go build -ldflags "-H windowsgui" .
考察
OSおよびアーキテクチャ固有のサフィックスを持つファイルは、build時にその制約に従うみたい。
参考:https://golang.org/pkg/go/build/