当前位置:首页 > 文章中心 > 正文内容

用GO+webview做个桌面程序

dgx6664个月前 (03-14)文章中心17

前两天我讲了bun+webview,今天我讲一下GO+webview。

GO语言有好多第三方的webview包,我个人感觉好用的是
github.com/webview/webview_go

安装包:

go get github.com/webview/webview_go

我下面的例子包含了web框架和winAPI

// main.go
package main

import (
	"io"
	"os"
	"unsafe"

	"github.com/labstack/echo/v4"
	"github.com/labstack/gommon/log"
	webview "github.com/webview/webview_go"
)

const (
	SW_MAXIMIZE = 3
	SW_MINIMIZE = 6
	SW_RESTORE  = 9
)

var (
	w webview.WebView
	h unsafe.Pointer
)

var (
	width  = 1280
	height = 720
	scale  = 1.0
)

func main() {

	//Message_Box("标题", "内容", 64)

	go func() {
		e := echo.New()
		e.Logger.SetLevel(log.OFF)
		e.Logger.SetOutput(io.Discard)
		e.Static("/", "app")
		e.Start("127.0.0.1:60088")
	}()

	args := os.Args

	if len(args) > 1 {
		if args[1] == "--debug" {
			w = webview.New(true)
		} else {
			os.Exit(0)
		}
	} else {
		w = webview.New(false)
		w.Init("document.addEventListener('keydown', function (event) {if ( (event.ctrlKey && event.key === 'r') || (event.ctrlKey && event.key === 'R') || event.key === 'F5') {event.preventDefault();}});")
		w.Init("document.addEventListener('contextmenu', function(event) {event.preventDefault();});")
	}

	defer w.Destroy()
	h = w.Window()
	w.SetTitle("MATAVIEW")
	w.SetSize(width, height, webview.HintNone)
	w.Bind("mata_win_minimize", win_minimize)
	w.Bind("mata_win_maximize", win_maximize)
	w.Bind("mata_win_restore", win_restore)
	w.Bind("mata_win_close", win_close)
	w.Bind("mata_win_center", win_center)
	w.Bind("mata_win_title", win_title)
	w.Init("window.mata={}")
	w.Init("window.mata.win={}")
	w.Init("window.mata.win.close=mata_win_close")
	w.Init("window.mata.win.minimize=mata_win_minimize")
	w.Init("window.mata.win.maximize=mata_win_maximize")
	w.Init("window.mata.win.restore=mata_win_restore")
	w.Init("window.mata.win.center=mata_win_center")
	w.Init("window.mata.win.title=mata_win_title")
	w.Navigate("http://127.0.0.1:60088/")

	var dpi, _ = Get_Dpi_For_System()
	scale = float64(dpi) / 96

	win_center()

	w.Run()

}

func win_size(ww int, hh int) {

}

func win_title(title string) {
	w.SetTitle(title)
}

func win_minimize() {
	Show_Window(h, SW_MINIMIZE)
}

func win_maximize() {
	Show_Window(h, SW_MAXIMIZE)
}

func win_restore() {
	Show_Window(h, SW_RESTORE)
}

func win_close() {
	w.Terminate()
}

func win_center() {
	screenWidth, _ := Get_System_Metrics(0)
	screenHeight, _ := Get_System_Metrics(1)
	realwidth := float64(width) * scale
	realheight := float64(height) * scale
	x := (screenWidth - int(realwidth)) / 2
	y := (screenHeight - int(realheight)) / 2
	Set_Window_Pos(h, 0, x, y, int(realwidth), int(realheight), 0)
}
// winapi.go
package main

import (
	"syscall"
	"unsafe"

	"golang.org/x/sys/windows"
)

var (
	user32           = syscall.NewLazyDLL("user32.dll")
	kernel32         = syscall.NewLazyDLL("kernel32.dll")
	FindWindow       = user32.NewProc("FindWindowW")
	ShowWindow       = user32.NewProc("ShowWindow")
	GetWindowRect    = user32.NewProc("GetWindowRect")
	GetSystemMetrics = user32.NewProc("GetSystemMetrics")
	SetWindowPos     = user32.NewProc("SetWindowPos")
	GetDpiForSystem  = user32.NewProc("GetDpiForSystem")
	GetDpiForWindow  = user32.NewProc("GetDpiForWindow")
	SetWindowLongW   = user32.NewProc("SetWindowLongW")
)

const (
	GWL_STYLE      = -16
	WS_MAXIMIZEBOX = 0x00010000
)

func Set_Window_LongW(hwnd unsafe.Pointer, nIndex int, dwNewLong float64) (uintptr, uintptr, error) {
	ret, ret2, err := SetWindowLongW.Call(uintptr(hwnd), uintptr(nIndex), uintptr(dwNewLong))
	return ret, ret2, err
}

func Show_Window(hwnd unsafe.Pointer, show int) error {

	ret, _, err := ShowWindow.Call(uintptr(hwnd), uintptr(show))
	if ret == 0 {
		return err
	}
	return nil
}

func Set_Window_Pos(hwnd unsafe.Pointer, hwndInsertAfter uintptr, x, y, cx, cy int, flags uint) error {
	ret, _, err := SetWindowPos.Call(
		uintptr(hwnd),
		hwndInsertAfter,
		uintptr(x),
		uintptr(y),
		uintptr(cx),
		uintptr(cy),
		uintptr(flags),
	)
	if ret == 0 {
		return err
	}
	return nil
}

func Ge_Window_Rect(hwnd unsafe.Pointer) (rect struct{ Left, Top, Right, Bottom int }, err error) {
	ret, _, err := GetWindowRect.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&rect)))
	if ret == 0 {
		return rect, err
	}
	return rect, nil
}

func Get_System_Metrics(nIndex int) (int, error) {
	ret, _, err := GetSystemMetrics.Call(uintptr(nIndex))
	if ret == 0 {
		return 0, err
	}
	return int(ret), nil
}

func Get_Dpi_For_System() (uint, error) {
	ret, _, err := GetDpiForSystem.Call()
	if ret == 0 {
		return 0, err
	}
	return uint(ret), nil
}

func Get_Dpi_For_Window(hwnd unsafe.Pointer) (uint, error) {
	ret, _, err := GetDpiForWindow.Call(uintptr(hwnd))
	if ret == 0 {
		return 0, err
	}
	return uint(ret), nil
}

func Message_Box(title string, message string, utype uint32) {
	hwnd := windows.HWND(0)
	ptitle, _ := syscall.UTF16PtrFromString(title)
	pmessage, _ := syscall.UTF16PtrFromString(message)
	windows.MessageBox(hwnd, pmessage, ptitle, utype)
}

如果你是我的老粉丝,你可以看出来这个就是我之前发布的MATAVIEW


下面是 精简版 MATAVIEW LITE源码

// main.go
package main

import (
	"strconv"
	"time"

	"github.com/labstack/echo"
	webview "github.com/webview/webview_go"
)

var w webview.WebView

func main() {

	go func() {
		e := echo.New()
		e.Debug = false
		e.HideBanner = true
		e.DisableHTTP2 = true
		e.Static("/", "./")
		e.Start("127.0.0.1:60088")
	}()

	now := time.Now()
	timestamp := strconv.FormatInt(now.UnixNano(), 10)

	w = webview.New(false)
	defer w.Destroy()
	w.Init("document.addEventListener('keydown', function (event) {if ( (event.ctrlKey && event.key === 'r') || (event.ctrlKey && event.key === 'R') || event.key === 'F5') {event.preventDefault();}});")
	w.Init("document.addEventListener('contextmenu', function(event) {event.preventDefault();});")
	w.Bind("win_size", win_size)
	w.Bind("win_close", win_close)
	w.Bind("win_title", win_title)
	w.Navigate("http://127.0.0.1:60088/?timestamp=" + timestamp)
	w.Run()

}

func win_size(width int, height int, htype int) {
	if htype == 0 {
		w.SetSize(width, height, webview.HintNone)
	} else {
		w.SetSize(width, height, webview.HintFixed)
	}

}

func win_close() {
	w.Terminate()
}

func win_title(title string) {
	w.SetTitle(title)
}
// index.html




    
    
    Document



    
    
    
    

win_size(长,宽,锁定)
win_title(标题)
win_close()
    
MATAVIEW LITE是MATAVIEW的精简版,只保留三个函数,程序是静态编译,只包含HTTP静态服务器和WEBVIEW2(还是要安装webview2 runtime,WIN10 2004版本及其以上自带),减少杀软误杀的几率。

下载地址:https://share.weiyun.com/uhgAsAKI
<script> win_title("MATAVIEW LITE") win_size(480, 800, 1) </script>

LITE版取消了WINAPI接口,只保留了webview_go的接口和echo框架,其实如果你不需要echo也可以删除。

扫描二维码推送至手机访问。

版权声明:本文由第六芝士网发布,如需转载请注明出处。

本文链接:http://www.dgx666.com/post/264.html

分享给朋友:

“用GO+webview做个桌面程序” 的相关文章

为什么win10、win11不能正常显示仿宋_GB2312字体格式

很多人发现新系统的仿宋_GB2312字体在Office Word里以默认的微软雅黑代替显示了,他们以为这是因为系统里只有仿宋字体,缺少仿宋_GB2312的缘故,于是下载仿宋_GB2312字体安装,结果发现然并卵。GB2312是老字库,只有两千多字,很多生僻字都无法正常显示,导致微软只留下包含很多生僻...

CAD2014提示致命错误怎么解决?

在很长一段时间里,朋友圈流传的这样一段话:世人慌慌张张,不过图碎银几两;可偏偏就是这几两碎银,能免饥荒,能定安康 ,能解世人惆怅。。。有些用户在使用CAD完成作品后,保存作品时出现了致命错误,听起来很可怕,这是怎么回事呢?有可能与电脑兼容性或者CAD版本有关,那么该怎么办呢?下面和大家分享CAD保存...

CAD启动太慢了?只需一键关闭这些按钮,即可快速启动CAD

工作紧急时,CAD不给力怎么办?启动太慢了,每次启动都要等上好半天,真的超级忧伤... 别急,想要快速启动CAD其实是有诀窍的。你只要学会下面这几招即可快速启动你的CAD了,那么下面我们就一起来看看吧。一、关闭通讯中心和联机帮助中心想要快速启动CAD,只要关闭通讯中心和联机帮助中心就行了。那么通讯中...

怎么把备忘录放桌面 怎么在桌面显示备忘录便签里的内容

手机上自带的备忘录app是很多人都使用过的一款软件,以iPhone为例,自从iOS系统升至iOS14版本以来,就新增了桌面小组件功能。为了方便自己的使用,提高查看内容的效率,怎么把备忘录放桌面?怎么在桌面显示备忘录便签里的内容?要想在iOS14及以上版本的iPhone手机桌面上摆放备忘录很简单,首先...

电脑好用便签软件推荐用哪个?PC端透明桌面便签

可以在Windows电脑端应用的便签软件琳琅满目,好用的便签软件推荐大家可关注敬业签,诸如工作、生活、学习等方面容易忘记的备忘任务都可以记录在敬业签中,使用时可以创建多个分类标签记录。记录类型多样化一、便签有需要保存的图片、文档、音频、视频、表格、PPT等文件可以用便签来记录,便签支持一键拖入多个文...

Origin2017中文版

在公众号里放了Origin的2017中文版,,,然后安装步骤上和之前的9略微有些不一样,,,然后有些小伙伴有疑问,这里重新发一下2017的安装步骤。安装安装完成之后跳出开始菜单的快捷方式文件夹。(不要运行)破解我第一次在虚拟机上安装的时候出现了一个缺少msvcr110.dll的错误,,,百度说是缺少...