>백엔드 개발 >Golang >화면의 최상위 창을 얻고 표시할 수 있는 프로그램을 golang에서 구현하는 방법

화면의 최상위 창을 얻고 표시할 수 있는 프로그램을 golang에서 구현하는 방법

PHPz
PHPz원래의
2023-04-25 09:11:381456검색

현재 컴퓨터 운영 체제에서 화면의 맨 위 레이어는 현재 표시되고 있는 창이나 애플리케이션을 나타냅니다. Windows 시스템에서는 Win32 API를 통해 최상위 창을 얻고 관리할 수 있습니다. 이 기사에서는 golang을 사용하여 화면의 최상위 창을 얻고 표시할 수 있는 프로그램을 구현하는 방법을 소개합니다.

  1. 최상위 창 목록 가져오기

golang에서는 syscall 패키지를 사용하여 시스템 수준 함수를 호출합니다. FindWindowEx 함수를 사용하여 최상위 창의 핸들 목록을 얻을 수 있습니다. 예를 들면 다음과 같습니다.

hwnd := uintptr(0)
var list []uintptr
for {
    hwnd = uintptr(C.FindWindowEx(
        0,
        hwnd,
        nil,
        nil,
    ))
    if hwnd == 0 {
        break
    }
    list = append(list, hwnd)
}

그 중 FindWindowEx 함수의 매개변수의 의미는 다음과 같습니다.

  • 첫 번째 매개변수는 검색이 시작되는 상위 창 핸들입니다. 0이면 바탕화면에서 검색이 시작됩니다.
  • 두 번째 매개변수는 이전 창의 핸들입니다. 0이면 첫 번째 창부터 검색을 시작합니다.
  • 세 번째 매개변수는 창 클래스 이름입니다. nil은 창 클래스 이름에 제한이 없음을 의미합니다.
  • 네 번째 매개변수는 창 제목이며, nil은 창 제목을 제한하지 않는다는 의미입니다.

반환값은 발견된 창 핸들이며, 발견되지 않으면 0이 반환됩니다.

  1. 최상위 창 정보 가져오기

창 핸들을 얻은 후 GetWindowRect 함수를 호출하여 창의 위치와 크기 정보를 얻을 수 있습니다. 예를 들면 다음과 같습니다.

var rect syscall.Rect
C.GetWindowRect(
    C.HWND(hwnd),
    (*C.RECT)(unsafe.Pointer(&rect)),
)

그 중 GetWindowRect 함수의 매개변수는 다음과 같은 의미를 갖습니다.

  • 첫 번째 매개변수는 창 핸들입니다.
  • 두 번째 매개변수는 창 위치와 크기 정보에 대한 포인터입니다.
  1. 최상위 창 정보 표시

창 위치와 크기 정보를 얻으면 golang의 그래픽 라이브러리를 사용하여 창의 썸네일을 표시할 수 있습니다. 예:

thumb, err := goscreenshot.CaptureWindowRect(rect)
if err != nil {
    log.Println(err)
    continue
}
screen, err := png.Decode(bytes.NewReader(thumb))
if err != nil {
    log.Println(err)
    continue
}
win := Window{
    Title:   title,
    X:       rect.Left,
    Y:       rect.Top,
    Width:   rect.Right - rect.Left,
    Height:  rect.Bottom - rect.Top,
    Picture: screen,
}
viewer.Show(win)

그 중 CaptureWindowRect 함수는 golang의 스크린샷 패키지를 통해 창 스크린샷 기능을 구현합니다. 그런 다음 golang의 image/png 패키지를 사용하여 이미지 데이터를 읽고 창에 표시합니다. 마지막으로 Window 구조가 정의되고 Viewer.Show 메서드를 사용하여 창 정보를 표시합니다.

  1. 전체 코드

전체 코드는 다음과 같습니다.

package main

import (
    "bytes"
    "image/png"
    "log"
    "unsafe"

    "github.com/lxn/walk"
    . "github.com/lxn/walk/declarative"
    "golang.org/x/sys/windows"
)

var (
    C = windows.NewLazySystemDLL("user32.dll")
)

// 窗口信息结构
type Window struct {
    Title   string      // 窗口标题
    X       int32       // 窗口左上角X坐标
    Y       int32       // 窗口左上角Y坐标
    Width   int32       // 窗口宽度
    Height  int32       // 窗口高度
    Picture image.Image // 窗口截图
}

func main() {

    // 创建窗口
    var mw *walk.MainWindow
    var tv *walk.TableView
    var viewer *walk.ImageView
    MainWindow{
        Title:   "Screen Viewer",
        MinSize: Size{640, 480},
        Layout:  VBox{},
        Children: []Widget{
            TableView{
                AssignTo:         &tv,
                AlternatingRowBG: true,
                Columns: []TableViewColumn{
                    {Title: "Title"},
                    {Title: "X"},
                    {Title: "Y"},
                    {Title: "Width"},
                    {Title: "Height"},
                },
            },
            ImageView{
                AssignTo: &viewer,
            },
        },
    }.Create(&mw)

    // 获取顶层窗口列表
    hwnd := uintptr(0)
    var list []uintptr
    for {
        hwnd = uintptr(C.FindWindowEx(
            0,
            hwnd,
            nil,
            nil,
        ))
        if hwnd == 0 {
            break
        }
        list = append(list, hwnd)
    }

    // 遍历窗口列表并显示窗口信息
    var data []Window
    for _, hwnd := range list {
        var rect syscall.Rect
        C.GetWindowRect(
            C.HWND(hwnd),
            (*C.RECT)(unsafe.Pointer(&rect)),
        )
        title := getWindowText(hwnd)
        if title == "" {
            continue
        }
        thumb, err := goscreenshot.CaptureWindowRect(rect)
        if err != nil {
            log.Println(err)
            continue
        }
        screen, err := png.Decode(bytes.NewReader(thumb))
        if err != nil {
            log.Println(err)
            continue
        }
        win := Window{
            Title:   title,
            X:       rect.Left,
            Y:       rect.Top,
            Width:   rect.Right - rect.Left,
            Height:  rect.Bottom - rect.Top,
            Picture: screen,
        }
        data = append(data, win)
        tv.PublishRowsReset()
    }

    // 设置模型
    model, _ := NewWindowModel(data)
    tv.SetModel(model)

    // 开始消息循环
    mw.Run()
}

// 获取窗口标题
func getWindowText(hwnd uintptr) string {
    var buf [256]uint16
    C.GetWindowText(
        C.HWND(hwnd),
        (*C.CHAR)(unsafe.Pointer(&buf)),
        256,
    )
    return syscall.UTF16ToString(buf[:])
}

// 窗口模型
type WindowModel struct {
    walk.TableModelBase
    items []Window
}

func NewWindowModel(items []Window) (*WindowModel, error) {
    m := new(WindowModel)

    m.items = items

    return m, nil
}

func (m *WindowModel) RowCount() int {
    return len(m.items)
}

func (m *WindowModel) Value(row, col int) interface{} {
    item := m.items[row]

    switch col {
    case 0:
        return item.Title

    case 1:
        return item.X

    case 2:
        return item.Y

    case 3:
        return item.Width

    case 4:
        return item.Height

    }

    panic("unexpected col")
}
  1. Summary

이 글에서는 golang을 사용하여 화면의 최상위 창을 구하고 표시하는 프로그램을 구현하는 방법을 소개합니다. Windows API 함수를 호출하고 창 스크린샷, 이미지 표시 등의 작업을 구현함으로써 간단한 스크린샷 도구를 쉽게 작성할 수 있습니다. 동시에 golang의 그래픽 라이브러리와 Windows API의 협력을 통해 크로스 플랫폼 애플리케이션을 작성할 수 있습니다.

위 내용은 화면의 최상위 창을 얻고 표시할 수 있는 프로그램을 golang에서 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.