Posted at

Macの上でWALKを使うWindowsアプリケーションをGO言語を使って書く

Mac上でWindowsプログラムを開発しないといけなくなった場合にお役立てください。

どうしたらそんな機会があるのかはわかりませんが、実際に私がやることになったので、世の中的にはあり得ることなのではないかと思います。


環境

もの
バージョン

macOS
10.14

Golang
1.11 darwin/amd64

wine
3.0.2

wineはhomebrewで適当に入れれば動くと思います。


なぜgolangなのか

Windowsアプリのクロスコンパイラとして有名なMinGWにg++が入っているので、C++でコードを書いてしまうのも手です。

というか、初めはC++で書くつもりでいました。

が、やはり非同期処理が難しく、(C++よりかは)使い慣れているgolangでgoroutineを使って非同期処理を書きたくなったためです。

あと文字列だとかの操作が圧倒的にgolangの方が楽というのもあり…

MinGW環境でBoostを使えば文字列の扱いがもうちょっと楽になったかもですが、私の低いC++力ではMinGW + Boostまで辿り着けなかったので、今回は諦めてgolangを使います。


ソース

WALKのReadmeに載っているサンプルコードをそのまま使います。


main.go

package main

import (
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
"strings"
)

func main() {
var inTE, outTE *walk.TextEdit

MainWindow{
Title: "SCREAMO",
MinSize: Size{600, 400},
Layout: VBox{},
Children: []Widget{
HSplitter{
Children: []Widget{
TextEdit{AssignTo: &inTE},
TextEdit{AssignTo: &outTE, ReadOnly: true},
},
},
PushButton{
Text: "SCREAM",
OnClicked: func() {
outTE.SetText(strings.ToUpper(inTE.Text()))
},
},
},
}.Run()
}



ビルド

$ GOOS=windows GOARCH=386 go get -u github.com/lxn/walk

$ GOOS=windows GOARCH=386 go build main.go

これで main.exe ができます。

go get の際にもGOOS などを指定しておかないと、WALKのgetに失敗します。


失敗

$ wine main.exe

何も表示されないままプログラムが終了してしまいます。


修正

WALKのissueによると、どうやらTooltip周りのパラメータが、特定の値でないと動作しない不具合があるようです。

(おそらくwine由来のもの?)

そこで、 $GOPATH/github.com/lxn/walk/tooltip.go の190行目(あたり)、 ti.CbSize に入る数値を 42 に固定します。

var ti win.TOOLINFO

ti.CbSize = 42 // <- ここ
ti.Hwnd = hwnd

これでもう一度ビルドを試みると、今度こそウィンドウが表示されます。

$ GOOS=windows GOARCH=386 go build main.go

$ wine main.exe

やりましたね! :tada:

ちなみにこの調子でgo-winioなど、他のWin32APIを使用するライブラリも使用可能です。

これで、Macしか持っていなくてもWindowsアプリ開発ができますね!!

もしWindowsアプリ開発を案件として請け負うなら素直にWindowsのPCを買った方がいいと思いますが。