Maison  >  Article  >  développement back-end  >  Comment implémenter un programme en Golang capable d'obtenir et d'afficher la fenêtre de niveau supérieur de l'écran

Comment implémenter un programme en Golang capable d'obtenir et d'afficher la fenêtre de niveau supérieur de l'écran

PHPz
PHPzoriginal
2023-04-25 09:11:381368parcourir

Dans les systèmes d'exploitation informatiques actuels, l'écran supérieur fait référence à la fenêtre ou à l'application en cours d'affichage. Dans les systèmes Windows, les fenêtres de niveau supérieur peuvent être obtenues et gérées via l'API Win32. Dans cet article, nous présenterons comment utiliser Golang pour implémenter un programme capable d'obtenir et d'afficher la fenêtre de niveau supérieur de l'écran.

  1. Obtenez la liste des fenêtres de niveau supérieur

Dans Golang, utilisez le package syscall pour appeler les fonctions au niveau du système. Nous pouvons utiliser la fonction FindWindowEx pour obtenir la liste des handles de la fenêtre de niveau supérieur. Par exemple :

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

Parmi eux, la signification des paramètres de la fonction FindWindowEx est la suivante :

  • Le premier paramètre est le handle de la fenêtre parent où commence la recherche. S'il vaut 0, la recherche démarre depuis le bureau.
  • Le deuxième paramètre est le handle de la fenêtre précédente. S'il vaut 0, la recherche démarre à partir de la première fenêtre.
  • Le troisième paramètre est le nom de la classe de fenêtre, nul signifie qu'il n'y a aucune restriction sur le nom de la classe de fenêtre.
  • Le quatrième paramètre est le titre de la fenêtre, nul signifie ne pas limiter le titre de la fenêtre.

La valeur de retour est le handle de fenêtre trouvé, s'il n'est pas trouvé, 0 est renvoyé.

  1. Obtenir des informations de niveau supérieur sur la fenêtre

Après avoir obtenu le handle de la fenêtre, nous pouvons appeler la fonction GetWindowRect pour obtenir les informations sur la position et la taille de la fenêtre. Par exemple :

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

Parmi eux, les paramètres de la fonction GetWindowRect ont les significations suivantes :

  • Le premier paramètre est le handle de la fenêtre.
  • Le deuxième paramètre est un pointeur vers les informations sur la position et la taille de la fenêtre.
  1. Afficher les informations de fenêtre de niveau supérieur

En obtenant les informations sur la position et la taille de la fenêtre, nous pouvons utiliser la bibliothèque graphique de Golang pour afficher la vignette de la fenêtre. Par exemple :

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)

Parmi eux, la fonction CaptureWindowRect implémente la fonction de capture d'écran de fenêtre via le package de capture d'écran de Golang. Utilisez ensuite le package image/png de golang pour lire les données de l'image et les afficher dans la fenêtre. Enfin, la structure Window est définie et la méthode viewer.Show est utilisée pour afficher les informations de la fenêtre.

  1. Code complet

Le code complet est le suivant :

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. Résumé

Cet article présente comment utiliser golang pour implémenter un programme permettant d'obtenir et d'afficher la fenêtre de niveau supérieur de l'écran. En appelant les fonctions de l'API Windows et en implémentant des opérations telles que des captures d'écran de fenêtres et l'affichage d'images, nous pouvons facilement écrire un outil de capture d'écran simple. Dans le même temps, avec la coopération de la bibliothèque graphique de Golang et de l'API Windows, nous pouvons écrire des applications multiplateformes.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn