ホームページ  >  記事  >  バックエンド開発  >  画面のトップレベルウィンドウを取得して表示できるプログラムをgolangで実装する方法

画面のトップレベルウィンドウを取得して表示できるプログラムをgolangで実装する方法

PHPz
PHPzオリジナル
2023-04-25 09:11:381366ブラウズ

現在のコンピュータ オペレーティング システムでは、画面の最上層は現在表示されているウィンドウまたはアプリケーションを指します。 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 の場合、検索はデスクトップから開始されます。
  • 2 番目のパラメータは前のウィンドウのハンドルで、0 の場合は最初のウィンドウから検索を開始します。
  • 3 番目のパラメータはウィンドウ クラス名です。nil はウィンドウ クラス名が制限されていないことを意味します。
  • 4 番目のパラメータはウィンドウのタイトルです。nil はウィンドウのタイトルを制限しないことを意味します。

戻り値は見つかったウィンドウハンドルで、見つからない場合は0を返します。

  1. トップレベルのウィンドウ情報の取得

ウィンドウ ハンドルを取得した後、GetWindowRect 関数を呼び出してウィンドウの位置とサイズの情報を取得できます。例:

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

このうち、GetWindowRect 関数のパラメーターの意味は次のとおりです。

  • 最初のパラメーターはウィンドウ ハンドルです。
  • 2 番目のパラメータは、ウィンドウの位置とサイズ情報へのポインタです。
  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. 概要

この記事では、次の内容を紹介します。 Golang の使い方 Golang は、画面のトップレベルウィンドウを取得して表示するプログラムを実装します。 Windows API関数を呼び出して、ウィンドウのスクリーンショットや画像表示などの操作を実装することで、簡単なスクリーンショットツールを作成できます。同時に、golang のグラフィック ライブラリと Windows API の連携により、クロスプラットフォーム アプリケーションを作成できます。

以上が画面のトップレベルウィンドウを取得して表示できるプログラムをgolangで実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。