Golang创建无边框窗体程序

By qq84628151 没有评论

1.主要核心库是 https://github.com/energye/energy

2.参考官网安装完energy开发环境后,编写golang代码

package main

import (
	"syscall"

	"github.com/energye/energy/v2/cef"
	"github.com/energye/energy/v2/cef/ipc"
	"github.com/energye/energy/v2/cef/ipc/context"
	"github.com/lxn/win"
)

var (
	orainWndProc uintptr
)

func main() {
	cef.GlobalInit(nil, nil)
	cefApp := cef.NewApplication()
	//本地网页路径
	cef.BrowserWindow.Config.Url = "http://localhost:3000/"
	cef.BrowserWindow.Config.EnableHideCaption = true
	cef.BrowserWindow.Config.Width = 1200
	cef.BrowserWindow.Config.Height = 800

	//窗体拖拽
	ipc.On("window-drag", func(context context.IContext) {
		win.ReleaseCapture()
		win.PostMessage(win.HWND(cef.BrowserWindow.MainWindow().Handle()), 274, 0xF010+0x0002, 0)
	})
	//窗体最小化、最大化、还原
	ipc.On("window-state", func(context context.IContext) {
		bw := cef.BrowserWindow.GetWindowInfo(context.BrowserId())
		state := context.ArgumentList().GetIntByIndex(0)
		if state == 0 {
			bw.Minimize()
		} else if state == 1 {
			bw.Maximize()
		} else if state == 2 {
			bw.Restore()
		}
	})
	//窗体关闭
	ipc.On("window-close", func(context context.IContext) {
		bw := cef.BrowserWindow.GetWindowInfo(context.BrowserId())
		bw.CloseBrowserWindow()
	})
	cef.BrowserWindow.SetBrowserInit(func(event *cef.BrowserEvent, window cef.IBrowserWindow) {
		defaultWndProcPtr := syscall.NewCallback(defaultWndProc)
		orainWndProc = win.SetWindowLongPtr(win.HWND(cef.BrowserWindow.MainWindow().Handle()), win.GWLP_WNDPROC, defaultWndProcPtr)
	})
	//Cef进入消息循环
	cef.Run(cefApp)
}

func defaultWndProc(hwnd win.HWND, msg uint32, wParam, lParam uintptr) (result uintptr) {
	switch msg {
	case win.WM_SIZE:
		if wParam == 0 || wParam == 2 {
			ipc.Emit("window-resize", wParam)
		}
	}
	return win.CallWindowProc(orainWndProc, hwnd, msg, wParam, lParam)
}

3.编写网页代码,这里代码用到React + Ant Design

import React, { useState, useRef, useEffect } from "react";
import { Layout, Menu, theme, Space, Button } from "antd";
import { UploadOutlined, UserOutlined, VideoCameraOutlined, MinusOutlined, BorderOutlined, CloseOutlined, SwitcherOutlined } from "@ant-design/icons";

const { Header, Footer, Sider, Content } = Layout;

const App: React.FC = () => {
  const {
    token: { colorBgContainer },
  } = theme.useToken();

  const headRef = useRef<any>();
  const [windowIsMax, setWindowIsMax] = useState<boolean>();
  const [menuSelect, setMenuSelect] = useState<string[]>(["2"]);

  const windowClose = () => {
    (window as any)?.ipc?.emit("window-close");
  };

  const windowMin = () => {
    (window as any)?.ipc?.emit("window-state", [0]);
  };

  const windowMaxOrReset = () => {
    (window as any)?.ipc?.emit("window-state", [windowIsMax ? 2 : 1]);
  };

  const windowDrag = (e: React.MouseEvent<any>) => {
    if (e.target == headRef.current) {
      (window as any)?.ipc?.emit("window-drag", [windowIsMax ? 2 : 1]);
    }
  };

  useEffect(() => {
    (window as any)?.ipc?.on("window-resize", function (status: any) {
      setWindowIsMax(status == 2);
    });
  }, []);

  return (
    <Layout style={{ width: "100vw", height: "100vh" }}>
      <Sider>
        <Menu
          theme="dark"
          mode="inline"
          selectedKeys={menuSelect}
          onSelect={(e) => setMenuSelect(e.selectedKeys)}
          items={[UserOutlined, VideoCameraOutlined, UploadOutlined, UserOutlined].map((icon, index) => ({
            key: String(index + 1),
            icon: React.createElement(icon),
            label: `nav ${index + 1}`,
          }))}
        />
      </Sider>
      <Layout>
        <Header ref={headRef} onMouseDown={windowDrag} style={{ padding: 0, background: colorBgContainer, height: "40px" }}>
          <Space size={0} style={{ float: "right" }}>
            <Button onClick={windowMin} style={{ verticalAlign: "top" }} type="text" icon={<MinusOutlined />}></Button>
            <Button onClick={windowMaxOrReset} style={{ verticalAlign: "top" }} type="text" icon={windowIsMax ? <SwitcherOutlined /> : <BorderOutlined />}></Button>
            <Button onClick={windowClose} style={{ verticalAlign: "top", color: "#000000e0" }} type="text" icon={<CloseOutlined />} danger></Button>
          </Space>
        </Header>
        <Content style={{ margin: "24px 16px 0" }}>
          <div style={{ padding: 24, minHeight: 360, background: colorBgContainer }}>content</div>
        </Content>
        <Footer style={{ textAlign: "center" }}>Ant Design ©2023 Created by Ant UED</Footer>
      </Layout>
    </Layout>
  );
};

export default App;

Golang无边框窗体已经实现,下面截图看看效果: