准备工作 #
go get github.com/akavel/rsrc
go get github.com/lxn/win
go get github.com/lxn/walk
简单示例 #
package main
import (
"log"
"github.com/lxn/win"
"github.com/lxn/walk"
. "github.com/lxn/walk/declarative"
)
type MyWindow struct {
*walk.MainWindow
hWnd win.HWND
ni *walk.NotifyIcon
}
func (mw *MyWindow) removeStyle(style int32) {
currStyle := win.GetWindowLong(mw.hWnd, win.GWL_STYLE)
win.SetWindowLong(mw.hWnd, win.GWL_STYLE, currStyle&style)
}
func (mw *MyWindow)GetIcon()walk.Image {
icon, err := walk.Resources.Image("img/check.ico")
if err != nil {
log.Fatal(err)
}
return icon
}
func (mw *MyWindow) AddNotifyIcon() {
var err error
mw.ni, err = walk.NewNotifyIcon(mw)
if err != nil {
log.Fatal(err)
}
_ = mw.ni.SetIcon(mw.GetIcon())
_ = mw.ni.SetVisible(true)
mw.ni.MouseDown().Attach(func(x, y int, button walk.MouseButton) {
if button == walk.LeftButton {
mw.Show()
win.ShowWindow(mw.Handle(), win.SW_RESTORE)
}
})
}
//使用declarative实现
func (mw *MyWindow)NewMainWindowEx(title string) {
if err := (MainWindow{
AssignTo: &mw.MainWindow ,
Title: title,
Size: Size{550, 380},
Layout: VBox{MarginsZero: true},
Children: []Widget{
},
}.Create()); err != nil {
log.Fatal(err)
}
}
//使用walk和win实现
func (mw *MyWindow)NewMainWindowEx1(title string) {
mw.MainWindow,_ = walk.NewMainWindow()
_ = mw.SetLayout(walk.NewVBoxLayout())
_ = mw.SetSize(walk.Size{Height: 380, Width: 550})
_ = mw.SetTitle(title)
_ = mw.SetX((int(win.GetSystemMetrics(0)) - mw.Width()) / 2)
_ = mw.SetY((int(win.GetSystemMetrics(1)) - mw.Height()) / 2)
mw.Show()
win.ShowWindow(mw.Handle(), win.SW_RESTORE)
}
//主程序
func main() {
mw := new(MyWindow)
mw.NewMainWindowEx1("托盘小程序")
mw.hWnd = mw.Handle()
_ = mw.SetIcon(mw.GetIcon())
mw.removeStyle(^win.WS_SIZEBOX)
mw.removeStyle(^win.WS_MAXIMIZEBOX)
mw.AddNotifyIcon()
mw.Run()
}
清单文件 main.manifest #
main.manifest
是 应用程序配置元数据
的 清单文件
-
main.manifest
保存在main.go
的同级目录下
-
直接复制 “文件内容” 即可,没特殊情况不用修改
-
解决win7/win8/win10应用程序兼容问题
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<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>
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
具体关于manifest的介绍和使用
https://blog.csdn.net/hellokittymeng/article/details/75574780
生成 / 编译: #
第一步:将 main.manifest
生成为 main.syso
#
这个步骤只需要运行一次,
调试/编译
只需一直执行
第二步
- 生成的
main.syso
是可以拿到别的 GUI 项目中使用的
- 除非你想修改
main.manifest
或者图标文件
才要重新生成一次 在当前窗口下
打开cmd
,运行如下命令:
rsrc -manifest main.manifest -o main.syso
第二步:编译成独立的 exe 文件 #
- 不管
调试
还是正式编译
,都必须通过双击 exe 文件运行
,无法使用go run main.go
直接运行 - 调试:
go build
- 正式编译:
go build -ldflags="-H windowsgui -w -s"
包提供示例在项目外部库的地址
github.com\lxn\walk@v0.0.0-20210112085537-c389da54e794\examples