Walk de Windows GUI

# Walk de Windows GUI

今回は、walkというpackageを使ってWindows GUIを作ってみます。

- lxn/walk: A Windows GUI toolkit for the Go Programming Language
  - <https://github.com/lxn/walk>

## インストール

いつもの

`go get -v github.com/lxn/walk`

でインストールされます。

## 準備

サンプル動かすだけならmanifestファイルいらないかもしれませんが、
これからGUIなexe作成するひとは、manifestファイルもあったほうが良いので

`go get -v github.com/akavel/rsrc`

もインストールしておくとよいです。

manifestファイルがないと、処理できることが限られてくる？
※ファイルをいじったりする処理のときに権限が付与されずエラーになったりします？

### manifestファイルを作成する

たしかいじらずに使えたはずですが、`SomeFunkyNameHere`あたりの名前を変えておくとよいかもです。

```xml:test.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
    </dependency>
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
        </windowsSettings>
    </application>
</assembly>
```

`test.manifest`としてカレントに保存して、`rsrc -manifest test.manifest -o rsrc.syso`を実行

あとは`go build`するだけで勝手に組み込まれます。1度作ればOK。

## サンプルコード

READMEに載っているサンプルコードを実行してみましょう。

```go:test.go
package main

import (
	"strings"

	"github.com/lxn/walk"
	. "github.com/lxn/walk/declarative"
)

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()
}

```

![sc1.png](https://qiita-image-store.s3.amazonaws.com/0/238600/0032c8ff-7c35-a21b-8ef4-a4597df659a8.png)

`go build`してできたexeを実行し、開いた画面に「honda」と入れて「SCREAM」ボタンを押してみました。

ソースコードに解説コメントをつけてみました。

画面を構成する「ボタン」などのことを「パーツ」と表現して説明していきます。

```go:test.go
func main() {
	var inTE, outTE *walk.TextEdit

	MainWindow{ // メイン画面
		Title:   "SCREAMO",      // タイトル
		MinSize: Size{600, 400}, // 開くウィンドウのサイズ(最小サイズ)
		Layout:  VBox{},         // レイアウト : 上下に重ねていく
		Children: []Widget{ // レイアウト内に収めるパーツ(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() // walk実行
}
```

`Layout`というところにパーツをどのように置いていくかを指定する構造体を入れます。
`Children`に構成するパーツを入れていく、入れ子構造になっています。

`HSplitter{}`を使うことによって左右にパーツを配置していけます。
※その中のChildrenにパーツをいれることで左右にパーツを追加していける

パーツの各構造体には設定できる値があり、いろいろな設定ができます。

```go
TextEdit{AssignTo: &outTE, ReadOnly: true}, // パーツ: テキストフォーム(読取専用)
```

各パーツにどういうものがあるかは、godocがあればよいのですが。。。
存在しないみたいなので、よく使いそうなものを軽くまとめておきます。

一応 TextEdit なら [textedit.go](https://github.com/lxn/walk/blob/master/textedit.go) のメソッドを見れば、何ができるかわかります。

## TextEdit

```go
var inTE *walk.TextEdit

// パーツのAssignToに 値を管理する変数 のポインタを渡す
TextEdit{AssignTo: &inTE} // テキストフォームが書き換わると inTE の値が変わる

str := inTE.Text() // テキストフォームの 値を取得する

inTE.SetText(`hoge`) // テキストフォームに hoge をセットする
inTE.SetReadOnly(true) // テキストフォームを読み取り専用にする
```

## PushButton

サンプルでは無名関数にて処理させていますが、外にだすこともできる

```go
PushButton {
    Text: "表示させる文字",
    OnClicked: mw.clicked,
},
```

## 実行時の黒いウィンドウ(コマンドプロンプト)を消す

実行するとコマンドプロンプトがでるときは、下記のコマンドでbuildする

`go build -ldflags="-H windowsgui"`

## その他のサンプルコード

下記に用途別でサンプルコードを置いてくれているので、のぞいてみるとよいです。

* https://github.com/lxn/walk/tree/master/examples

## まとめ

すこし作るのに手間がかかりますが
Windows GUI をGo言語のソースだけで作成できてしまうのは良いですね。

packegeもたまに更新されているみたいなので、ちょっと期待しています。
みなさんも触ってみてみてくださいね～。