attachments-2021-11-HdAzMLrd61a42afb874e3.png

小编整理了有关golang开发windows桌面的知识,希望对你有所帮助:

在 awesome-go 节点下有不少开发界面的库, 大部分是基于web, gtk, qt跨平台的, 也有基于sciter go绑定的go-sciter, 基于原生包装的跨平台的库ui, 只支持Windows桌面端的walk

个人倾向于后2个, 适合个人的技术栈, 试用了下ui这个库, demo比较 少就4个, 运行起来有点卡, 而且生成的可执行文件很大. 最重要的是不支持设置控件坐标(没找到), 而且开放的接口比较少.

下面对比下ui和walk代码, 就拿button控件来说. - ui

attachments-2021-11-F4C2ATmk61a42b4732a8f.png

  • walk
  • type Button struct {
  •     WidgetBase
  •     checkedChangedPublisher EventPublisher
  •     clickedPublisher        EventPublisher
  •     textChangedPublisher    EventPublisher
  •     imageChangedPublisher   EventPublisher
  •     image                   Image
  •     persistent              bool
  • }

  • type WidgetBase struct {
  •     WindowBase
  •     parent                      Container
  •     toolTipTextProperty         Property
  •     toolTipTextChangedPublisher EventPublisher
  •     graphicsEffects             *WidgetGraphicsEffectList
  •     alwaysConsumeSpace          bool
  • }

  • type WindowBase struct {
  •     window                  Window
  •     hWnd                    win.HWND
  •     origWndProcPtr          uintptr
  •     name                    string
  •     font                    *Font
  •     contextMenu             *Menu
  •     disposables             []Disposable
  •     disposingPublisher      EventPublisher
  •     dropFilesPublisher      DropFilesEventPublisher
  •     keyDownPublisher        KeyEventPublisher
  •     keyPressPublisher       KeyEventPublisher
  •     keyUpPublisher          KeyEventPublisher
  •     mouseDownPublisher      MouseEventPublisher
  •     mouseUpPublisher        MouseEventPublisher
  •     mouseMovePublisher      MouseEventPublisher
  •     mouseWheelPublisher     MouseEventPublisher
  •     boundsChangedPublisher  EventPublisher
  •     sizeChangedPublisher    EventPublisher
  •     maxSize                 Size
  •     minSize                 Size
  •     background              Brush
  •     cursor                  Cursor
  •     suspended               bool
  •     visible                 bool
  •     enabled                 bool
  •     name2Property           map[string]Property
  •     enabledProperty         Property
  •     enabledChangedPublisher EventPublisher
  •     visibleProperty         Property
  •     visibleChangedPublisher EventPublisher
  •     focusedProperty         Property
  •     focusedChangedPublisher EventPublisher
  •     calcTextSizeInfoPrev    *calcTextSizeInfo
  • }

只列出了属性, 没有列出方法. 但也可以看出来ui这个库开放的接口非常少. 而walk这个库, 该有的都有了, 接口非常丰富. 实现的控件非常多, 甚至连webview都有, 例子也丰富不少.

需要注意的这个库里面的控件是基于原生控件的, 而不是自己绘制的

walk使用

attachments-2021-11-3nZ9f9Jf61a42b6f1b262.png

有点类似flutter中的申明式构建界面, 但是没有提供代码初始化的回调^^.

win使用

walk内部调用了win, 而win就干了一件事, 把win32 api几乎所有相关的声明都导成了go.

比如win32里面的ShowWindow, 是这么导出的:

attachments-2021-11-huUMKLJh61a42b84a8781.png

这样我们用go来调用win32 api, 跟c基本没差别, 除了语法上的略微差别. 我试用了下, 还是有个把方法没有导出. 可以按照这个方式自己导出.

既然该有的win32接口都有了, 那么就用go创建一个最简单的windows窗口吧

func main() {

    hInst := GetModuleHandle(nil)

    hIcon := LoadIcon(0, MAKEINTRESOURCE(IDI_APPLICATION))

    hCursor := LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW))


    var wc WNDCLASSEX

    wc.CbSize = uint32(unsafe.Sizeof(wc))

    wc.LpfnWndProc = syscall.NewCallback(wndProc)

    wc.HInstance = hInst

    wc.HIcon = hIcon

    wc.HCursor = hCursor

    wc.HbrBackground = COLOR_WINDOW + 1

    wc.LpszClassName = syscall.StringToUTF16Ptr("go windwow")

    wc.Style = CS_HREDRAW | CS_VREDRAW

    RegisterClassEx(&wc)


    hWnd := CreateWindowEx(

        0,

        syscall.StringToUTF16Ptr("go windwow"),

        syscall.StringToUTF16Ptr("go windwow"),

        WS_OVERLAPPEDWINDOW,

        400,

        200,

        640,

        480,

        0,

        0,

        hInst,

        nil)

    ShowWindow(hWnd, SW_SHOW)

    UpdateWindow(hWnd)


    var msg MSG

    for {

        if (GetMessage(&msg, 0, 0, 0) == TRUE) {

            TranslateMessage(&msg)

            DispatchMessage(&msg)

        } else {

            break

        }

    }

}


func wndProc(hwnd HWND, msg uint32, wParam, lParam uintptr) (result uintptr) {

    var ps PAINTSTRUCT

    switch msg {

    case WM_PAINT:

        hdc := BeginPaint(hwnd, &ps)


        var lb LOGBRUSH

        lb.LbStyle = BS_SOLID

        lb.LbColor = 0xff000

        lb.LbHatch = 0


        hPen := HGDIOBJ(ExtCreatePen(PS_SOLID, 2, &lb, 0, nil))

        hOldOpen := SelectObject(hdc, hPen)


        var pt POINT

        MoveToEx(hdc, 0, 0, &pt)

        LineTo(hdc, 100, 100)

        EndPaint(hwnd, &ps)


        SelectObject(hdc, hOldOpen)

        DeleteObject(hPen)

        break

    case WM_DESTROY:

        PostQuitMessage(0)

        break

    default:

        return DefWindowProc(hwnd, msg, wParam, lParam)

    }

    return 0

}

是不是基本与c的写法一模一样, 包括命名. 因此用go(win), 也能像c/c++一样开发windows界面, 只用稍微切换下语法.

而walk虽然把传统win32 api和控件封装成了对象, 把基于消息的事件包装成了回调, 封装出了canvs, 也有布局容器BoxLayout, 做做简单的界面还是很方便的, 但是其本质还是基于windows原有控件, 想自由布局, 定制界面, 性能方面还是很受限.

个人感觉可以win为基础封装自己的库, 比如用go把duilib翻译一遍, 这就又是另一番苦力活了.

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-A271v1xr62b14025703a6.jpeg