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

用GO+webview做个桌面程序

dgx6663个月前 (03-14)文章中心10

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

CAD如何彻底删除卸载保证能正常安装?

很多同学CAD遇到出问题(通常是激活失效或者功能异常)。匆忙的把CAD卸载了重新安装,要么是重新安装过程中提示CAD已经安装。要么是安装过程中安装路径是灰色的不可选。要么是好不容易能安装,最后提示安装失败。出现此类问题的原因是上一次卸载过程中CAD没有彻底卸载干净。很多同学简单的认为卸载CAD,就是...

AutoCAD各版本对应的R版本参数值及图形的不同版本代号

有时候我们进行CAD平台的二次开发时需要知道AutoCAD2002或AutoCAD2014等版本对应的是R多少的问题,或者卸载软件需要注册表删除的时候,经常需要知道AutoCAD各版本对应的R版本参数值。现将整理如下。AutoCAD 2002 (R15.0)AutoCAD 2004 (R16.0)...

CAD图纸中标注引线或多重引线怎么操作?

CAD是一种专业的制图软件,这里所说的CAD就是一款用于建筑、机械等产品构造以及电子产品结构设计的软件。在CAD使用中,经常会使用各种标注,为了让我们标注的文字更加明显,我们经常会使用各种引线来做提示,那么CAD的标注引线或多重引线如何使用?下面来告诉大家。方法/步骤第1步双击我们桌面上方中的CAD...

CAD插座符号怎么画出来,怎么画插座布置图?

插座是我们在使用AutoCAD绘图时经常会遇到的图形对象,也是建筑电器设计中频率非常高的绘制对象,今天小编与大家分享一下如图在CAD中绘制插座。1、首先打开CAD文件,点击“任意布置”或者“矩形布置”,再在弹出的电气图块中点击右上方的下拉菜单,再选择其中的“插座”选项,如下图所示2、再在电气图块的对...

DirectX修复工具-拯救你的游戏无法打开报错等问题-附使用教程

使用此工具可以帮您解决运行游戏中出现的未知错误,使您可以顺利的启动游戏软件下载地址:DirectX修复工具-DirectX_RepairV4.3 - 对岸网说明:这款软件有三种版本,分别是标准版、增强版、在线修复版,三款区别如下图所示软件简介:DirectX修复工具(DirectX Repair)是...

DirectX修复工具有什么用

DirectX修复工具有什么用方舟开服需要用到DirectX修复工具跟大家详细说说DirectX修复工具有什么用DirectX修复工具(DirectX Repair)官方最新版是一款优秀的系统DLL检测修复工具,DirectX不仅能够轻松的检测出电脑中缺失的.dll文件,还能够对其进行修复,并且兼容...