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

用GO+webview做个桌面程序

dgx6669个月前 (03-14)文章中心53

前两天我讲了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做个桌面程序” 的相关文章

AMD发布25.2.1图形驱动,新增支持《怪物猎人:荒野》等游戏

IT之家 2 月 12 日消息,AMD 昨日(2 月 11 日)发布 GPU 驱动更新 25.2.1 版本,重点新增支持《宣誓》、《席德梅尔的文明 VII》、《怪物猎人:荒野》以及《人中之龙 8 外传:夏威夷海盗》四款游戏。IT之家援引官方更新日志,附上 AMD 25.2.1 更新修复内容如下:修复...

高版本CAD没有经典模式怎么办?6步就能把CAD界面设置回经典模式

在设计行业工作时间比较长的同志,他们都用过比较老版本的CAD软件,老版本的CAD软件的经典工作界面,很多老设计师都非常熟悉。但随着时代更替,CAD软件的工作界面发生了很大变化。从2CAD010版开始,一直到现在CAD都是用新界面。CAD2010到CAD2014都保留了经典模式,但CAD2015版本开...

cad安装完成,某些产品无法安装

安装CAD的时候,出现安装完成,某些产品无法安装的情况。主要原因是由于系统本身的组件未达到软件所需的要求导致,所以我们要做的是重新补装所需组件。1、找到安装包以下路径:AutoCAD_2014\3rdParty\NET\4\wcu\dotNetFramework(注意,这里是安装目录,具体路径取决于...

CAD入门基础内容

CAD制图会有入门和中高级之分,一开始要有很多知识点要记,但很多刚开始学的小伙伴可能还不了解,下面是我就来介绍一下CAD入门基础内容,希望大家能有所收获!打开CAD2007绘图界面,点击“绘图”,在下拉菜单中选择“点”。然后选择“单点”,命令窗口中将出现“指定点”的命令,在绘图界面中可以绘制单点。绘...

如何在圆柱与圆锥面上绘制文字,关键在于SolidWorks包覆命令

今天给大家分享一个小技巧,是关于包覆命令在圆柱和圆锥面上的如何使用进行文字内容绘制,以及需要注意的事项。1. 首先我们打开 Solidworks2018软件,点击拉伸凸台,选择上视基准面,绘制一个圆,如图所示:2. 我们绘制好草图之后,选择完成,点击拉伸,如图所示:3.完成拉伸后,我们选择草图里面的...

电脑桌面便签在哪设置?备忘录软件哪个好?

好记性不如烂笔头!相信很多打工族在电脑面前办公的时候,都需要随时记录工作中的事项,有的用TXT记录,有的手写笔记,还有一些用电脑桌面便签类软件。而当我们待办事项繁多的时候,手写或文本记录并不能有效帮我们分好轻重缓急以及到点提醒我们。这种情况下,如果有一款可以设置提醒的电脑桌面便签软件来帮助我们,就可...